Make a GtkCellEditable (get_widget_window_size): Change to let it honor
authorJonathan Blandford <jrb@redhat.com>
Tue, 25 Sep 2001 16:44:39 +0000 (16:44 +0000)
committerJonathan Blandford <jrb@src.gnome.org>
Tue, 25 Sep 2001 16:44:39 +0000 (16:44 +0000)
Tue Sep 25 12:34:42 2001  Jonathan Blandford  <jrb@redhat.com>

* gtk/gtkentry.c: Make a GtkCellEditable
(get_widget_window_size): Change to let it honor size_allocate
when a CellEditable.

* gtk/gtktreeview.c: M-x clean-line-ends.  Lots of focus and
editable changes.
(gtk_tree_view_set_cursor): Now you can set the cursor
horizontally, as well as start editing.

* gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
code to look more like the other check buttons.

* gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
Change the way we calculate cell size.

* gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.

* demos/gtk-demo/sizegroup.c: Add mnemonics.

* gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
Fix logic.

* gtk/gtkcellrenderertext.c: Change to be editable.

* gtk/gtkcellrenderertoggle.c: Change to be activatable.

* test/testtreesort.c: Fix misspelling

* test/testreecolumns.c: Add mnemonics.

* test/testreeedit.c: New test program.

30 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
demos/gtk-demo/appwindow.c
demos/gtk-demo/sizegroup.c
docs/tree-column-sizing.txt
gtk/gtkcellrenderer.c
gtk/gtkcellrenderertext.c
gtk/gtkcellrenderertext.h
gtk/gtkcellrenderertoggle.c
gtk/gtkcellrenderertoggle.h
gtk/gtkentry.c
gtk/gtkentry.h
gtk/gtkmarshal.list
gtk/gtkmarshalers.list
gtk/gtkstyle.c
gtk/gtktreeprivate.h
gtk/gtktreeview.c
gtk/gtktreeview.h
gtk/gtktreeviewcolumn.c
gtk/gtktreeviewcolumn.h
tests/Makefile.am
tests/testtreecolumns.c
tests/testtreeedit.c [new file with mode: 0644]
tests/testtreefocus.c
tests/testtreesort.c

index bb81bc4b98fe633fdeb6078b54059f1e49fbcef6..b3dc1a47311d6c449c830d89f336dff05baa8097 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtkentry.c: Make a GtkCellEditable
+       (get_widget_window_size): Change to let it honor size_allocate
+       when a CellEditable.
+
+       * gtk/gtktreeview.c: M-x clean-line-ends.  Lots of focus and
+       editable changes.
+       (gtk_tree_view_set_cursor): Now you can set the cursor
+       horizontally, as well as start editing.
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+       code to look more like the other check buttons.
+
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+       Change the way we calculate cell size.
+
+       * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+       * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+       Fix logic.
+
+       * gtk/gtkcellrenderertext.c: Change to be editable.
+
+       * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+       * test/testtreesort.c: Fix misspelling
+
+       * test/testreecolumns.c: Add mnemonics.
+
+       * test/testreeedit.c: New test program.
+
 2001-09-25  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
index bb81bc4b98fe633fdeb6078b54059f1e49fbcef6..b3dc1a47311d6c449c830d89f336dff05baa8097 100644 (file)
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtkentry.c: Make a GtkCellEditable
+       (get_widget_window_size): Change to let it honor size_allocate
+       when a CellEditable.
+
+       * gtk/gtktreeview.c: M-x clean-line-ends.  Lots of focus and
+       editable changes.
+       (gtk_tree_view_set_cursor): Now you can set the cursor
+       horizontally, as well as start editing.
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+       code to look more like the other check buttons.
+
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+       Change the way we calculate cell size.
+
+       * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+       * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+       Fix logic.
+
+       * gtk/gtkcellrenderertext.c: Change to be editable.
+
+       * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+       * test/testtreesort.c: Fix misspelling
+
+       * test/testreecolumns.c: Add mnemonics.
+
+       * test/testreeedit.c: New test program.
+
 2001-09-25  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
index bb81bc4b98fe633fdeb6078b54059f1e49fbcef6..b3dc1a47311d6c449c830d89f336dff05baa8097 100644 (file)
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtkentry.c: Make a GtkCellEditable
+       (get_widget_window_size): Change to let it honor size_allocate
+       when a CellEditable.
+
+       * gtk/gtktreeview.c: M-x clean-line-ends.  Lots of focus and
+       editable changes.
+       (gtk_tree_view_set_cursor): Now you can set the cursor
+       horizontally, as well as start editing.
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+       code to look more like the other check buttons.
+
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+       Change the way we calculate cell size.
+
+       * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+       * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+       Fix logic.
+
+       * gtk/gtkcellrenderertext.c: Change to be editable.
+
+       * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+       * test/testtreesort.c: Fix misspelling
+
+       * test/testreecolumns.c: Add mnemonics.
+
+       * test/testreeedit.c: New test program.
+
 2001-09-25  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
index bb81bc4b98fe633fdeb6078b54059f1e49fbcef6..b3dc1a47311d6c449c830d89f336dff05baa8097 100644 (file)
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtkentry.c: Make a GtkCellEditable
+       (get_widget_window_size): Change to let it honor size_allocate
+       when a CellEditable.
+
+       * gtk/gtktreeview.c: M-x clean-line-ends.  Lots of focus and
+       editable changes.
+       (gtk_tree_view_set_cursor): Now you can set the cursor
+       horizontally, as well as start editing.
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+       code to look more like the other check buttons.
+
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+       Change the way we calculate cell size.
+
+       * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+       * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+       Fix logic.
+
+       * gtk/gtkcellrenderertext.c: Change to be editable.
+
+       * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+       * test/testtreesort.c: Fix misspelling
+
+       * test/testreecolumns.c: Add mnemonics.
+
+       * test/testreeedit.c: New test program.
+
 2001-09-25  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
index bb81bc4b98fe633fdeb6078b54059f1e49fbcef6..b3dc1a47311d6c449c830d89f336dff05baa8097 100644 (file)
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtkentry.c: Make a GtkCellEditable
+       (get_widget_window_size): Change to let it honor size_allocate
+       when a CellEditable.
+
+       * gtk/gtktreeview.c: M-x clean-line-ends.  Lots of focus and
+       editable changes.
+       (gtk_tree_view_set_cursor): Now you can set the cursor
+       horizontally, as well as start editing.
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+       code to look more like the other check buttons.
+
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+       Change the way we calculate cell size.
+
+       * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+       * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+       Fix logic.
+
+       * gtk/gtkcellrenderertext.c: Change to be editable.
+
+       * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+       * test/testtreesort.c: Fix misspelling
+
+       * test/testreecolumns.c: Add mnemonics.
+
+       * test/testreeedit.c: New test program.
+
 2001-09-25  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
index bb81bc4b98fe633fdeb6078b54059f1e49fbcef6..b3dc1a47311d6c449c830d89f336dff05baa8097 100644 (file)
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtkentry.c: Make a GtkCellEditable
+       (get_widget_window_size): Change to let it honor size_allocate
+       when a CellEditable.
+
+       * gtk/gtktreeview.c: M-x clean-line-ends.  Lots of focus and
+       editable changes.
+       (gtk_tree_view_set_cursor): Now you can set the cursor
+       horizontally, as well as start editing.
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+       code to look more like the other check buttons.
+
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+       Change the way we calculate cell size.
+
+       * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+       * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+       Fix logic.
+
+       * gtk/gtkcellrenderertext.c: Change to be editable.
+
+       * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+       * test/testtreesort.c: Fix misspelling
+
+       * test/testreecolumns.c: Add mnemonics.
+
+       * test/testreeedit.c: New test program.
+
 2001-09-25  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
index bb81bc4b98fe633fdeb6078b54059f1e49fbcef6..b3dc1a47311d6c449c830d89f336dff05baa8097 100644 (file)
@@ -1,3 +1,37 @@
+Tue Sep 25 12:34:42 2001  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtkentry.c: Make a GtkCellEditable
+       (get_widget_window_size): Change to let it honor size_allocate
+       when a CellEditable.
+
+       * gtk/gtktreeview.c: M-x clean-line-ends.  Lots of focus and
+       editable changes.
+       (gtk_tree_view_set_cursor): Now you can set the cursor
+       horizontally, as well as start editing.
+
+       * gtk/gtkstyle.c (gtk_default_draw_check): changing toggle drawing
+       code to look more like the other check buttons.
+
+       * gtk/gtkcellrenderertoggle.c (gtk_cell_renderer_toggle_get_size):
+       Change the way we calculate cell size.
+
+       * gtk/gtkmarshal.list (VOID:STRING,STRING): new marshaller.
+
+       * demos/gtk-demo/sizegroup.c: Add mnemonics.
+
+       * gtk/gtkcellrenderer.c (gtk_cell_renderer_get_size): Fix docs.
+       Fix logic.
+
+       * gtk/gtkcellrenderertext.c: Change to be editable.
+
+       * gtk/gtkcellrenderertoggle.c: Change to be activatable.
+
+       * test/testtreesort.c: Fix misspelling
+
+       * test/testreecolumns.c: Add mnemonics.
+
+       * test/testreeedit.c: New test program.
+
 2001-09-25  Havoc Pennington  <hp@pobox.com>
 
        * gtk/gtkwindow.c: Put notes in gtk_window_set_has_frame(),
index fd86d8dd9c5e35e1d70af40ea83012102a838858..cb88dc7fe878b7c922a6fd63d9de00788e41fcc7 100644 (file)
@@ -43,12 +43,12 @@ static GtkItemFactoryEntry menu_items[] =
   { "/File/sep1",        NULL,         menuitem_cb,       0, "<Separator>" },
   { "/File/_Quit",       "<control>Q", menuitem_cb,       0, "<StockItem>", GTK_STOCK_QUIT },
 
-  { "/_Preferences",                   NULL, 0,               0, "<Branch>" },
-  { "/_Preferences/_Color",            NULL, 0,               0, "<Branch>" },
-  { "/_Preferences/Color/_Red",        NULL, menuitem_cb, 0, "<RadioItem>" },
-  { "/_Preferences/Color/_Green",      NULL, menuitem_cb, 0, "/Preferences/Color/Red" },
+  { "/_Preferences",                    NULL, 0,               0, "<Branch>" },
+  { "/_Preferences/_Color",             NULL, 0,               0, "<Branch>" },
+  { "/_Preferences/Color/_Red",         NULL, menuitem_cb, 0, "<RadioItem>" },
+  { "/_Preferences/Color/_Green",       NULL, menuitem_cb, 0, "/Preferences/Color/Red" },
   { "/_Preferences/Color/_Blue",        NULL, menuitem_cb, 0, "/Preferences/Color/Red" },
-  { "/_Preferences/_Shape",            NULL, 0,               0, "<Branch>" },
+  { "/_Preferences/_Shape",             NULL, 0,               0, "<Branch>" },
   { "/_Preferences/Shape/_Square",      NULL, menuitem_cb, 0, "<RadioItem>" },
   { "/_Preferences/Shape/_Rectangle",   NULL, menuitem_cb, 0, "/Preferences/Shape/Square" },
   { "/_Preferences/Shape/_Oval",        NULL, menuitem_cb, 0, "/Preferences/Shape/Rectangle" },
index fe87feff50e4bda16e5426acabcfea1d3576106a..536dd745324a860024b4ce0596da2df1bff67fe6 100644 (file)
@@ -52,7 +52,7 @@ add_row (GtkTable     *table,
   GtkWidget *option_menu;
   GtkWidget *label;
 
-  label = gtk_label_new (label_text);
+  label = gtk_label_new_with_mnemonic (label_text);
   gtk_misc_set_alignment (GTK_MISC (label), 0, 1);
   gtk_table_attach (GTK_TABLE (table), label,
                    0, 1,                  row, row + 1,
@@ -60,6 +60,7 @@ add_row (GtkTable     *table,
                    0,                     0);
   
   option_menu = create_option_menu (options);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), option_menu);
   gtk_size_group_add_widget (size_group, option_menu);
   gtk_table_attach (GTK_TABLE (table), option_menu,
                    1, 2,                  row, row + 1,
@@ -137,8 +138,8 @@ do_sizegroup (void)
       gtk_table_set_col_spacings (GTK_TABLE (table), 10);
       gtk_container_add (GTK_CONTAINER (frame), table);
 
-      add_row (GTK_TABLE (table), 0, size_group, "Foreground", color_options);
-      add_row (GTK_TABLE (table), 1, size_group, "Background", color_options);
+      add_row (GTK_TABLE (table), 0, size_group, "_Foreground", color_options);
+      add_row (GTK_TABLE (table), 1, size_group, "_Background", color_options);
 
       /* And another frame holding line style options
        */
@@ -151,11 +152,11 @@ do_sizegroup (void)
       gtk_table_set_col_spacings (GTK_TABLE (table), 10);
       gtk_container_add (GTK_CONTAINER (frame), table);
 
-      add_row (GTK_TABLE (table), 0, size_group, "Dashing", dash_options);
-      add_row (GTK_TABLE (table), 1, size_group, "Line ends", end_options);
+      add_row (GTK_TABLE (table), 0, size_group, "_Dashing", dash_options);
+      add_row (GTK_TABLE (table), 1, size_group, "_Line ends", end_options);
 
       /* And a check button to turn grouping on and off */
-      check_button = gtk_check_button_new_with_label ("Enable grouping");
+      check_button = gtk_check_button_new_with_mnemonic ("_Enable grouping");
       gtk_box_pack_start (GTK_BOX (vbox), check_button, FALSE, FALSE, 0);
       
       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
index 367755fe538ebe4b9ff6c52e77c0045387472473..09e872434a038cf8ef36da13eee246246dcf64c0 100644 (file)
@@ -30,7 +30,7 @@ HOW THE GTKTREEVIEWCOLUMN STORES SIZE:
 ======================================
 
 There are a number of size related fields in the GtkTreeViewColumn
-structure:
+structure.  These are all valid after realization:
 
   sizing           The sizing method to use when calculating the size
                    of the column.  Can be grow_only, resizable, auto, and fixed.
index 4cd5ae493a7d422a28d9b33cede20ab813ea5cd6..651dc7f7a8f9e8fbbecddd457bb5589062fdd8ef 100644 (file)
@@ -318,7 +318,9 @@ gtk_cell_renderer_set_property (GObject      *object,
  * Obtains the width and height needed to render the cell. Used by view widgets
  * to determine the appropriate size for the cell_area passed to
  * gtk_cell_renderer_render().  If @cell_area is not %NULL, fills in the x and y
- * offsets (if set) of the cell relative to this location.
+ * offsets (if set) of the cell relative to this location.  Please note that the
+ * values set in @width and @height, as well as those in @x_offset and @y_offset
+ * are inclusive of the xpad and ypad properties.
  **/
 void
 gtk_cell_renderer_get_size (GtkCellRenderer *cell,
@@ -329,29 +331,24 @@ gtk_cell_renderer_get_size (GtkCellRenderer *cell,
                            gint            *width,
                            gint            *height)
 {
-  gint *real_width = NULL;
-  gint *real_height = NULL;
+  gint *real_width = width;
+  gint *real_height = height;
 
   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
   g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->get_size != NULL);
 
-  if (width)
+  if (width && cell->width != -1)
     {
-      if (cell->width == -1)
-       real_width = width;
-      else
-       *width = cell->width;
+      real_width = NULL;
+      *width = cell->width;
     }
-  if (height)
+  if (height && cell->height != -1)
     {
-      if (cell->height == -1)
-       real_height = height;
-      else
-       *height = cell->height;
+      real_height = NULL;
+      *height = cell->height;
     }
 
-  if (real_width || real_height)
-    GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell, widget, cell_area, x_offset, y_offset, real_width, real_height);
+  GTK_CELL_RENDERER_GET_CLASS (cell)->get_size (cell, widget, cell_area, x_offset, y_offset, real_width, real_height);
 }
 
 /**
@@ -364,15 +361,13 @@ gtk_cell_renderer_get_size (GtkCellRenderer *cell,
  * @expose_area: area that actually needs updating
  * @flags: flags that affect rendering
  *
- * Invokes the virtual render function of the #GtkCellRenderer. The
- * three passed-in rectangles are areas of @window. Most renderers
- * will draw to @cell_area; the xalign, yalign, xpad, and ypad fields
- * of the #GtkCellRenderer should be honored with respect to
- * @cell_area. @background_area includes the blank space around the
- * cell, and also the area containing the tree expander; so the
- * @background_area rectangles for all cells tile to cover the entire
- * @window. Cell renderers can use the @background_area to draw custom expanders, for
- * example. @expose_area is a clip rectangle.
+ * Invokes the virtual render function of the #GtkCellRenderer. The three
+ * passed-in rectangles are areas of @window. Most renderers will draw within
+ * @cell_area; the xalign, yalign, xpad, and ypad fields of the #GtkCellRenderer
+ * should be honored with respect to @cell_area. @background_area includes the
+ * blank space around the cell, and also the area containing the tree expander;
+ * so the @background_area rectangles for all cells tile to cover the entire
+ * @window.  @expose_area is a clip rectangle.
  *
  **/
 void
@@ -384,11 +379,6 @@ gtk_cell_renderer_render (GtkCellRenderer     *cell,
                          GdkRectangle        *expose_area,
                          GtkCellRendererState flags)
 {
-  /* It's actually okay to pass in a NULL cell, as we run into that
-   * a lot
-   */
-  if (cell == NULL)
-    return;
   g_return_if_fail (GTK_IS_CELL_RENDERER (cell));
   g_return_if_fail (GTK_CELL_RENDERER_GET_CLASS (cell)->render != NULL);
 
@@ -407,8 +397,8 @@ gtk_cell_renderer_render (GtkCellRenderer     *cell,
  * @event: a #GdkEvent
  * @widget: widget that received the event
  * @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
- * @background_area: background area as passed to gtk_cell_renderer_render()
- * @cell_area: cell area as passed to gtk_cell_renderer_render()
+ * @background_area: background area as passed to @gtk_cell_renderer_render
+ * @cell_area: cell area as passed to @gtk_cell_renderer_render
  * @flags: render flags
  *
  * Passes an activate event to the cell renderer for possible processing.  Some
@@ -449,8 +439,8 @@ gtk_cell_renderer_activate (GtkCellRenderer      *cell,
  * @event: a #GdkEvent
  * @widget: widget that received the event
  * @path: widget-dependent string representation of the event location; e.g. for #GtkTreeView, a string representation of #GtkTreePath
- * @background_area: background area as passed to gtk_cell_renderer_render()
- * @cell_area: cell area as passed to gtk_cell_renderer_render()
+ * @background_area: background area as passed to @gtk_cell_renderer_render
+ * @cell_area: cell area as passed to @gtk_cell_renderer_render
  * @flags: render flags
  * 
  * Passes an activate event to the cell renderer for possible processing.
index 0055dff58b1a0cd888781d68f2fdfcfdda8bced4..bced2d8c14149871001faa9a3c5eb20b66c886bc 100644 (file)
@@ -19,6 +19,9 @@
 
 #include <stdlib.h>
 #include "gtkcellrenderertext.h"
+#include "gtkeditable.h"
+#include "gtkentry.h"
+#include "gtksignal.h"
 #include "gtkintl.h"
 
 static void gtk_cell_renderer_text_init       (GtkCellRendererText      *celltext);
@@ -48,7 +51,18 @@ static void gtk_cell_renderer_text_render     (GtkCellRenderer          *cell,
                                               GdkRectangle             *expose_area,
                                               guint                     flags);
 
+static GtkCellEditable *gtk_cell_renderer_text_start_editing (GtkCellRenderer      *cell,
+                                                             GdkEvent             *event,
+                                                             GtkWidget            *widget,
+                                                             gchar                *path,
+                                                             GdkRectangle         *background_area,
+                                                             GdkRectangle         *cell_area,
+                                                             GtkCellRendererState  flags);
 
+enum {
+  EDITED,
+  LAST_SIGNAL
+};
 
 enum {
   PROP_0,
@@ -94,6 +108,9 @@ enum {
 };
 
 static gpointer parent_class;
+static guint text_cell_renderer_signals [LAST_SIGNAL];
+
+#define GTK_CELL_RENDERER_TEXT_PATH "gtk-cell-renderer-text-path"
 
 GtkType
 gtk_cell_renderer_text_get_type (void)
@@ -128,7 +145,7 @@ gtk_cell_renderer_text_init (GtkCellRendererText *celltext)
   GTK_CELL_RENDERER (celltext)->yalign = 0.5;
   GTK_CELL_RENDERER (celltext)->xpad = 2;
   GTK_CELL_RENDERER (celltext)->ypad = 2;
-
+  GTK_CELL_RENDERER (celltext)->mode = GTK_CELL_RENDERER_MODE_EDITABLE;
   celltext->fixed_height_rows = -1;
   celltext->font = pango_font_description_new ();
 }
@@ -148,7 +165,8 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
 
   cell_class->get_size = gtk_cell_renderer_text_get_size;
   cell_class->render = gtk_cell_renderer_text_render;
-
+  cell_class->start_editing = gtk_cell_renderer_text_start_editing;
+  
   g_object_class_install_property (object_class,
                                    PROP_TEXT,
                                    g_param_spec_string ("text",
@@ -390,6 +408,17 @@ gtk_cell_renderer_text_class_init (GtkCellRendererTextClass *class)
   ADD_SET_PROP ("underline_set", PROP_UNDERLINE_SET,
                 _("Underline set"),
                 _("Whether this tag affects underlining"));
+
+  text_cell_renderer_signals [EDITED] =
+    gtk_signal_new ("edited",
+                   GTK_RUN_LAST,
+                   GTK_CLASS_TYPE (object_class),
+                   GTK_SIGNAL_OFFSET (GtkCellRendererTextClass, edited),
+                   gtk_marshal_VOID__STRING_STRING,
+                   GTK_TYPE_NONE, 2,
+                   G_TYPE_STRING,
+                   G_TYPE_STRING);
+
 }
 
 static void
@@ -1135,12 +1164,12 @@ gtk_cell_renderer_text_get_size (GtkCellRenderer *cell,
       if (x_offset)
        {
          *x_offset = cell->xalign * (cell_area->width - rect.width - (2 * cell->xpad));
-         *x_offset = MAX (*x_offset, 0) + cell->xpad;
+         *x_offset = MAX (*x_offset, 0);
        }
       if (y_offset)
        {
          *y_offset = cell->yalign * (cell_area->height - rect.height - (2 * cell->ypad));
-         *y_offset = MAX (*y_offset, 0) + cell->ypad;
+         *y_offset = MAX (*y_offset, 0);
        }
     }
 
@@ -1202,7 +1231,7 @@ gtk_cell_renderer_text_render (GtkCellRenderer    *cell,
 
       g_object_unref (G_OBJECT (gc));
     }
-  
+
   gtk_paint_layout (widget->style,
                     window,
                     state,
@@ -1210,12 +1239,60 @@ gtk_cell_renderer_text_render (GtkCellRenderer    *cell,
                     cell_area,
                     widget,
                     "cellrenderertext",
-                    cell_area->x + x_offset,
-                    cell_area->y + y_offset,
+                    cell_area->x + x_offset + cell->xpad,
+                    cell_area->y + y_offset + cell->ypad,
                     layout);
 
   g_object_unref (G_OBJECT (layout));
 }
+static void
+gtk_cell_renderer_text_editing_done (GtkCellEditable *entry,
+                                    gpointer         data)
+{
+  gchar *path;
+  gchar *new_text;
+
+  path = g_object_get_data (G_OBJECT (entry), GTK_CELL_RENDERER_TEXT_PATH);
+  new_text = gtk_entry_get_text (GTK_ENTRY (entry));
+
+  gtk_signal_emit (GTK_OBJECT (data), text_cell_renderer_signals[EDITED], path, new_text);
+}
+
+static GtkCellEditable *
+gtk_cell_renderer_text_start_editing (GtkCellRenderer      *cell,
+                                     GdkEvent             *event,
+                                     GtkWidget            *widget,
+                                     gchar                *path,
+                                     GdkRectangle         *background_area,
+                                     GdkRectangle         *cell_area,
+                                     GtkCellRendererState  flags)
+{
+  GtkCellRendererText *celltext;
+  GtkWidget *entry;
+  
+  celltext = GTK_CELL_RENDERER_TEXT (cell);
+
+  /* If the cell isn't editable we return NULL. */
+  if (celltext->editable == FALSE)
+    return NULL;
+
+  entry = g_object_new (GTK_TYPE_ENTRY,
+                       "has_frame", FALSE,
+                       NULL);
+
+  gtk_entry_set_text (GTK_ENTRY (entry), celltext->text);
+  g_object_set_data_full (G_OBJECT (entry), GTK_CELL_RENDERER_TEXT_PATH, g_strdup (path), g_free);
+  
+  gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
+  
+  gtk_widget_show (entry);
+  gtk_signal_connect (GTK_OBJECT (entry),
+                     "editing_done",
+                     G_CALLBACK (gtk_cell_renderer_text_editing_done),
+                     celltext);
+  return GTK_CELL_EDITABLE (entry);
+
+}
 
 /**
  * gtk_cell_renderer_text_set_fixed_height_from_font:
@@ -1226,8 +1303,9 @@ gtk_cell_renderer_text_render (GtkCellRenderer    *cell,
  * "y_pad" property set on it.  Further changes in these properties do not
  * affect the height, so they must be accompanied by a subsequent call to this
  * function.  Using this function is unflexible, and should really only be used
- * if calculating the size of a cell is too slow.  If @no_rows is -1, then the
- * fixed height is unset, and the height is determined by the properties again.
+ * if calculating the size of a cell is too slow (ie, a massive number of cells
+ * displayed).  If @number_of_rows is -1, then the fixed height is unset, and
+ * the height is determined by the properties again.
  **/
 void
 gtk_cell_renderer_text_set_fixed_height_from_font (GtkCellRendererText *renderer,
index 41a8fcb7e49f308c0c298c7bb4f699d5018339b1..dfc4f8b3dbfdd83faeabed21fed0a437f1184e49 100644 (file)
@@ -79,6 +79,10 @@ struct _GtkCellRendererText
 struct _GtkCellRendererTextClass
 {
   GtkCellRendererClass parent_class;
+
+  void (* edited) (GtkCellRendererText *cell_renderer_text,
+                  gchar               *path,
+                  gchar               *new_text);
 };
 
 GtkType          gtk_cell_renderer_text_get_type (void);
index fac7dd7bd98d95bf891ee27ca19e42d48763d6d6..845266f6e7867136b55625a1d42906e11eb69592 100644 (file)
@@ -62,6 +62,7 @@ enum {
 
 enum {
   PROP_ZERO,
+  PROP_ACTIVATABLE,
   PROP_ACTIVE,
   PROP_RADIO
 };
@@ -101,6 +102,7 @@ gtk_cell_renderer_toggle_get_type (void)
 static void
 gtk_cell_renderer_toggle_init (GtkCellRendererToggle *celltoggle)
 {
+  celltoggle->activatable = TRUE;
   celltoggle->active = FALSE;
   celltoggle->radio = FALSE;
   GTK_CELL_RENDERER (celltoggle)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
@@ -130,6 +132,15 @@ gtk_cell_renderer_toggle_class_init (GtkCellRendererToggleClass *class)
                                                         G_PARAM_READABLE |
                                                         G_PARAM_WRITABLE));
   
+  g_object_class_install_property (object_class,
+                                  PROP_ACTIVATABLE,
+                                  g_param_spec_boolean ("activatable",
+                                                        _("Activatable"),
+                                                        _("The toggle button can be activated"),
+                                                        TRUE,
+                                                        G_PARAM_READABLE |
+                                                        G_PARAM_WRITABLE));
+
   g_object_class_install_property (object_class,
                                   PROP_RADIO,
                                   g_param_spec_boolean ("radio",
@@ -163,6 +174,9 @@ gtk_cell_renderer_toggle_get_property (GObject     *object,
     case PROP_ACTIVE:
       g_value_set_boolean (value, celltoggle->active);
       break;
+    case PROP_ACTIVATABLE:
+      g_value_set_boolean (value, celltoggle->activatable);
+      break;
     case PROP_RADIO:
       g_value_set_boolean (value, celltoggle->radio);
       break;
@@ -187,6 +201,10 @@ gtk_cell_renderer_toggle_set_property (GObject      *object,
       celltoggle->active = g_value_get_boolean (value);
       g_object_notify (G_OBJECT(object), "active");
       break;
+    case PROP_ACTIVATABLE:
+      celltoggle->activatable = g_value_get_boolean (value);
+      g_object_notify (G_OBJECT(object), "activatable");
+      break;
     case PROP_RADIO:
       celltoggle->radio = g_value_get_boolean (value);
       g_object_notify (G_OBJECT(object), "radio");
@@ -241,13 +259,13 @@ gtk_cell_renderer_toggle_get_size (GtkCellRenderer *cell,
     {
       if (x_offset)
        {
-         *x_offset = cell->xalign * (cell_area->width - calc_width - (2 * cell->xpad));
-         *x_offset = MAX (*x_offset, 0) + cell->xpad;
+         *x_offset = cell->xalign * (cell_area->width - calc_width);
+         *x_offset = MAX (*x_offset, 0);
        }
       if (y_offset)
        {
-         *y_offset = cell->yalign * (cell_area->height - calc_height - (2 * cell->ypad));
-         *y_offset = MAX (*y_offset, 0) + cell->ypad;
+         *y_offset = cell->yalign * (cell_area->height - calc_height);
+         *y_offset = MAX (*y_offset, 0);
        }
     }
 }
@@ -281,21 +299,17 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
   if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
     {
       if (GTK_WIDGET_HAS_FOCUS (widget))
-       {
-         state = GTK_STATE_SELECTED;
-       }
+       state = GTK_STATE_SELECTED;
       else
-       {
-         state = GTK_STATE_ACTIVE;
-       }
+       state = GTK_STATE_ACTIVE;
     }
-  else if (cell->mode == GTK_CELL_RENDERER_MODE_INERT)
+  else if (celltoggle->activatable)
     {
-      state = GTK_STATE_INSENSITIVE;
+      state = GTK_STATE_NORMAL;
     }
   else
     {
-      state = GTK_STATE_NORMAL;
+      state = GTK_STATE_INSENSITIVE;
     }
 
   if (celltoggle->radio)
@@ -306,7 +320,7 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
                         cell_area, widget, "cellradio",
                         cell_area->x + x_offset + cell->xpad,
                         cell_area->y + y_offset + cell->ypad,
-                        width, height);
+                        width - 1, height - 1);
     }
   else
     {
@@ -316,7 +330,7 @@ gtk_cell_renderer_toggle_render (GtkCellRenderer *cell,
                        cell_area, widget, "cellcheck",
                        cell_area->x + x_offset + cell->xpad,
                        cell_area->y + y_offset + cell->ypad,
-                       width, height);
+                       width - 1, height - 1);
     }
 }
 
@@ -330,24 +344,15 @@ gtk_cell_renderer_toggle_activate (GtkCellRenderer *cell,
                                   guint            flags)
 {
   GtkCellRendererToggle *celltoggle;
-  gboolean retval = FALSE;
   
   celltoggle = GTK_CELL_RENDERER_TOGGLE (cell);
-  
-  switch (event->type)
+  if (celltoggle->activatable)
     {
-    case GDK_BUTTON_PRESS:
-      {
-        gtk_signal_emit (GTK_OBJECT (cell), toggle_cell_signals[TOGGLED], path);
-        retval = TRUE;
-      }
-      break;
-
-    default:
-      break;
+      gtk_signal_emit (GTK_OBJECT (cell), toggle_cell_signals[TOGGLED], path);
+      return TRUE;
     }
-      
-  return retval;
+
+  return FALSE;
 }
 
 /**
index f1918e1cfa999c6ba1ddf576d1d7d64c7fb66c8e..db166112fb3e4114323f4373ff75e226707e42bf 100644 (file)
@@ -43,6 +43,7 @@ struct _GtkCellRendererToggle
 
   /*< private >*/
   guint active : 1;
+  guint activatable : 1;
   guint radio : 1;
 };
 
@@ -50,7 +51,7 @@ struct _GtkCellRendererToggleClass
 {
   GtkCellRendererClass parent_class;
 
-  void (* toggled) (GtkCellRendererToggle *celltoggle,
+  void (* toggled) (GtkCellRendererToggle *cell_renderer_toggle,
                    gchar                 *path);
 };
 
index 0715097f2b2506254c42e353774386a9f7234eda..c8931e481804cbb9888f5c5f0a7772aefc396154 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "gdk/gdkkeysyms.h"
 #include "gtkbindings.h"
+#include "gtkcelleditable.h"
 #include "gtkclipboard.h"
 #include "gtkdnd.h"
 #include "gtkentry.h"
@@ -100,8 +101,9 @@ static GtkTargetEntry target_table[] = {
 
 /* GObject, GtkObject methods
  */
-static void   gtk_entry_class_init           (GtkEntryClass    *klass);
-static void   gtk_entry_editable_init        (GtkEditableClass *iface);
+static void   gtk_entry_class_init           (GtkEntryClass        *klass);
+static void   gtk_entry_editable_init        (GtkEditableClass     *iface);
+static void   gtk_entry_cell_editable_init   (GtkCellEditableIface *iface);
 static void   gtk_entry_init                 (GtkEntry         *entry);
 static void   gtk_entry_set_property (GObject         *object,
                                      guint            prop_id,
@@ -189,6 +191,11 @@ static gboolean gtk_entry_get_selection_bounds (GtkEditable *editable,
                                                gint        *start,
                                                gint        *end);
 
+/* GtkCellEditable method implementations
+ */
+static void gtk_entry_start_editing (GtkCellEditable *cell_editable,
+                                    GdkEvent        *event);
+
 /* Default signal handlers
  */
 static void gtk_entry_real_insert_text   (GtkEntry        *entry,
@@ -298,10 +305,20 @@ gtk_entry_get_type (void)
        NULL                                             /* interface_data */
       };
 
+      static const GInterfaceInfo cell_editable_info =
+      {
+       (GInterfaceInitFunc) gtk_entry_cell_editable_init,    /* interface_init */
+       NULL,                                                 /* interface_finalize */
+       NULL                                                  /* interface_data */
+      };
+      
       entry_type = gtk_type_unique (GTK_TYPE_WIDGET, &entry_info);
       g_type_add_interface_static (entry_type,
                                   GTK_TYPE_EDITABLE,
                                   &editable_info);
+      g_type_add_interface_static (entry_type,
+                                  GTK_TYPE_CELL_EDITABLE,
+                                  &cell_editable_info);
     }
 
   return entry_type;
@@ -763,6 +780,12 @@ gtk_entry_editable_init (GtkEditableClass *iface)
   iface->get_position = gtk_entry_get_position;
 }
 
+static void
+gtk_entry_cell_editable_init (GtkCellEditableIface *iface)
+{
+  iface->start_editing = gtk_entry_start_editing;
+}
+
 static void
 gtk_entry_set_property (GObject         *object,
                         guint            prop_id,
@@ -881,7 +904,7 @@ gtk_entry_init (GtkEntry *entry)
   entry->invisible_char = '*';
   entry->dnd_position = -1;
   entry->width_chars = -1;
-  
+  entry->is_cell_renderer = FALSE;
   entry->has_frame = TRUE;
   
   gtk_drag_dest_set (GTK_WIDGET (entry),
@@ -1179,13 +1202,23 @@ get_widget_window_size (GtkEntry *entry,
     *x = widget->allocation.x;
 
   if (y)
-    *y = widget->allocation.y + (widget->allocation.height - requisition.height) / 2;
+    {
+      if (entry->is_cell_renderer)
+       *y = widget->allocation.y;
+      else
+       *y = widget->allocation.y + (widget->allocation.height - requisition.height) / 2;
+    }
 
   if (width)
     *width = widget->allocation.width;
 
   if (height)
-    *height = requisition.height;
+    {
+      if (entry->is_cell_renderer)
+       *height = widget->allocation.height;
+      else
+       *height = requisition.height;
+    }
 }
 
 static void
@@ -1777,6 +1810,43 @@ gtk_entry_style_set      (GtkWidget      *widget,
     }
 }
 
+/* GtkCellEditable method implementations
+ */
+static void
+gtk_cell_editable_entry_activated (GtkEntry *entry, gpointer data)
+{
+  gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry));
+  gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry));
+}
+
+static gboolean
+gtk_cell_editable_key_press_event (GtkEntry    *entry,
+                                  GdkEventKey *key_event,
+                                  gpointer     data)
+{
+    if (key_event->keyval == GDK_Escape)
+      {
+       gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry));
+       gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry));
+
+       return TRUE;
+      }
+
+    return FALSE;
+}
+
+static void
+gtk_entry_start_editing (GtkCellEditable *cell_editable,
+                        GdkEvent        *event)
+{
+  GTK_ENTRY (cell_editable)->is_cell_renderer = TRUE;
+
+  g_signal_connect (G_OBJECT (cell_editable), "activate",
+                   G_CALLBACK (gtk_cell_editable_entry_activated), NULL);
+  g_signal_connect (G_OBJECT (cell_editable), "key_press_event",
+                   G_CALLBACK (gtk_cell_editable_key_press_event), NULL);
+}
+
 /* Default signal handlers
  */
 static void
index 5ec2049e4921cbb76d5d8096f136ab57c7484896..90b7bf5b5a0cefedf266a032cf8b02a2080da614 100644 (file)
@@ -84,7 +84,9 @@ struct _GtkEntry
   guint        cursor_visible : 1;
 
   guint        in_click : 1;   /* Flag so we don't select all when clicking in entry to focus in */
-  
+
+  guint        is_cell_renderer : 1;
+
   guint   button;
   guint   blink_timeout;
   guint   recompute_idle;
index 186140fbaa6a31cc54416a210db572bded0d3df2..23a66260e6cad4aa0b40d6ed95bfb47c96f9a892 100644 (file)
@@ -77,6 +77,7 @@ VOID:POINTER,INT
 VOID:POINTER,POINTER,POINTER
 VOID:POINTER,UINT
 VOID:STRING
+VOID:STRING,STRING
 VOID:STRING,INT,POINTER
 VOID:UINT,BOXED,UINT,FLAGS,FLAGS
 VOID:UINT,OBJECT,UINT,FLAGS,FLAGS
index 186140fbaa6a31cc54416a210db572bded0d3df2..23a66260e6cad4aa0b40d6ed95bfb47c96f9a892 100644 (file)
@@ -77,6 +77,7 @@ VOID:POINTER,INT
 VOID:POINTER,POINTER,POINTER
 VOID:POINTER,UINT
 VOID:STRING
+VOID:STRING,STRING
 VOID:STRING,INT,POINTER
 VOID:UINT,BOXED,UINT,FLAGS,FLAGS
 VOID:UINT,OBJECT,UINT,FLAGS,FLAGS
index 5a91aab43343d29b86bad17b560db34b72c3db47..d3a7fc7c2e81c9261d9a2f576027cc0855162a66 100644 (file)
@@ -3018,19 +3018,12 @@ gtk_default_draw_check (GtkStyle      *style,
                           x, y,
                          width, height);
 
+      x -= (1 + INDICATOR_PART_SIZE - width) / 2;
+      y -= (((1 + INDICATOR_PART_SIZE - height) / 2) - 1);
       if (shadow_type == GTK_SHADOW_IN)
        {
-         gdk_draw_line (window,
-                        widget->style->fg_gc[state_type],
-                         x, y,
-                         x + width,
-                         y + height);
-         gdk_draw_line (window,
-                        widget->style->fg_gc[state_type],
-                         x + width,
-                         y,
-                         x,
-                         y + height);
+         draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
+         draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
        }
     }
   else
index 33235b5feb5151d6d3cb2c1c15ab5e9b8079bb7c..5ffedf56e2b77d66a6303df5af1b7e38923580df 100644 (file)
@@ -109,7 +109,6 @@ struct _GtkTreeViewPrivate
 
   /* Focus code */
   GtkTreeViewColumn *focus_column;
-  GtkTreeViewColumn *scroll_column;
 
   /* Selection stuff */
   GtkTreeRowReference *anchor;
index 9b6366e3c84bcf1f8646b1ab5275ca2270d7edb7..c0a180d6afeaeab59559b7f27b1e2cbe6fa489e5 100644 (file)
@@ -106,6 +106,7 @@ enum
   TOGGLE_CURSOR_ROW,
   EXPAND_COLLAPSE_CURSOR_ROW,
   SELECT_CURSOR_PARENT,
+  START_INTERACTIVE_SEARCH,
   LAST_SIGNAL
 };
 
@@ -313,6 +314,8 @@ static void     gtk_tree_view_check_dirty_and_clean          (GtkTreeView
 static void     gtk_tree_view_clamp_node_visible             (GtkTreeView       *tree_view,
                                                              GtkRBTree         *tree,
                                                              GtkRBNode         *node);
+static void     gtk_tree_view_clamp_column_visible           (GtkTreeView       *tree_view,
+                                                             GtkTreeViewColumn *column);
 static gboolean gtk_tree_view_maybe_begin_dragging_row       (GtkTreeView       *tree_view,
                                                              GdkEventMotion    *event);
 static void     _gtk_tree_view_update_col_width              (GtkTreeView       *tree_view);
@@ -337,8 +340,6 @@ static gboolean gtk_tree_view_real_expand_row                (GtkTreeView
 static void     gtk_tree_view_real_set_cursor                (GtkTreeView       *tree_view,
                                                              GtkTreePath       *path,
                                                              gboolean           clear_and_select);
-static void     gtk_tree_view_ensure_focus_column            (GtkTreeView       *tree_view);
-
 
 /* interactive search */
 static void     gtk_tree_view_search_dialog_destroy     (GtkWidget        *search_dialog,
@@ -370,25 +371,27 @@ static gboolean gtk_tree_view_search_iter               (GtkTreeModel     *model
                                                         gint              n);
 static void     gtk_tree_view_search_init               (GtkWidget        *entry,
                                                         GtkTreeView      *tree_view);
-static void     gtk_tree_view_interactive_search        (GtkTreeView      *tree_view,
-                                                        GdkEventKey      *key);
 static void     gtk_tree_view_put                       (GtkTreeView      *tree_view,
                                                         GtkWidget        *child_widget,
                                                         gint              x,
                                                         gint              y,
                                                         gint              width,
                                                         gint              height);
-static void gtk_tree_view_start_editing (GtkTreeView       *tree_view,
-                                        GtkTreeViewColumn *column,
-                                        GtkCellEditable   *cell_editable,
-                                        GdkRectangle      *cell_area,
-                                        GdkEvent          *event,
-                                        guint              flags);
-static void gtk_tree_view_stop_editing (GtkTreeView       *tree_view);
+static gboolean gtk_tree_view_start_editing             (GtkTreeView      *tree_view,
+                                                        GtkTreePath      *cursor_path);
+static void gtk_tree_view_real_start_editing (GtkTreeView       *tree_view,
+                                             GtkTreeViewColumn *column,
+                                             GtkTreePath       *path,
+                                             GtkCellEditable   *cell_editable,
+                                             GdkRectangle      *cell_area,
+                                             GdkEvent          *event,
+                                             guint              flags);
+static void gtk_tree_view_stop_editing                  (GtkTreeView *tree_view);
+static void gtk_tree_view_real_start_interactive_search (GtkTreeView *tree_view);
 
 
 static GtkContainerClass *parent_class = NULL;
-static guint tree_view_signals[LAST_SIGNAL] = { 0 };
+static guint tree_view_signals [LAST_SIGNAL] = { 0 };
 
 \f
 
@@ -482,6 +485,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
   class->toggle_cursor_row = gtk_tree_view_real_toggle_cursor_row;
   class->expand_collapse_cursor_row = gtk_tree_view_real_expand_collapse_cursor_row;
   class->select_cursor_parent = gtk_tree_view_real_select_cursor_parent;
+  class->start_interactive_search = gtk_tree_view_real_start_interactive_search;
 
   /* Properties */
 
@@ -556,7 +560,7 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
                                                           _("View allows user to search through columns interactively"),
                                                           TRUE,
                                                           G_PARAM_READWRITE));
-    
+
     g_object_class_install_property (o_class,
                                     PROP_SEARCH_COLUMN,
                                     g_param_spec_int ("search_column",
@@ -566,40 +570,46 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
                                                       G_MAXINT,
                                                       0,
                                                       G_PARAM_READWRITE));
-    
+
   /* Style properties */
-  /* the width of the column resize windows */
 #define _TREE_VIEW_EXPANDER_SIZE 10
 #define _TREE_VIEW_VERTICAL_SEPARATOR 2
-#define _TREE_VIEW_HORIZONTAL_SEPARATOR 0
+#define _TREE_VIEW_HORIZONTAL_SEPARATOR 2
 
   gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_int ("expander_size",
                                                             _("Expander Size"),
-                                                            _("Size of the expander arrow"),
+                                                            _("Size of the expander arrow."),
                                                             0,
                                                             G_MAXINT,
                                                             _TREE_VIEW_EXPANDER_SIZE,
                                                             G_PARAM_READABLE));
-  
+
   gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_int ("vertical_separator",
                                                             _("Vertical Separator Width"),
-                                                            _("Vertical space between cells"),
+                                                            _("Vertical space between cells.  Must be an even number."),
                                                             0,
                                                             G_MAXINT,
                                                             _TREE_VIEW_VERTICAL_SEPARATOR,
                                                             G_PARAM_READABLE));
-  
+
   gtk_widget_class_install_style_property (widget_class,
                                           g_param_spec_int ("horizontal_separator",
                                                             _("Horizontal Separator Width"),
-                                                            _("Horizontal space between cells"),
+                                                            _("Horizontal space between cells.  Must be an even number."),
                                                             0,
                                                             G_MAXINT,
                                                             _TREE_VIEW_HORIZONTAL_SEPARATOR,
                                                             G_PARAM_READABLE));
 
+  gtk_widget_class_install_style_property (widget_class,
+                                          g_param_spec_boolean ("allow_rules",
+                                                                _("Allow Rules"),
+                                                                _("Allow drawing of alternating color rows."),
+                                                                TRUE,
+                                                                G_PARAM_READABLE));
+
   /* Signals */
   widget_class->set_scroll_adjustments_signal =
     gtk_signal_new ("set_scroll_adjustments",
@@ -718,6 +728,15 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
                   gtk_marshal_NONE__NONE,
                   GTK_TYPE_NONE, 0);
 
+  tree_view_signals[START_INTERACTIVE_SEARCH] =
+    g_signal_new ("start_interactive_search",
+                  G_TYPE_FROM_CLASS (object_class),
+                  G_SIGNAL_RUN_LAST | GTK_RUN_ACTION,
+                  G_STRUCT_OFFSET (GtkTreeViewClass, start_interactive_search),
+                  NULL, NULL,
+                  gtk_marshal_NONE__NONE,
+                  GTK_TYPE_NONE, 0);
+
   /* Key bindings */
   gtk_tree_view_add_move_binding (binding_set, GDK_Up, 0,
                                  GTK_MOVEMENT_DISPLAY_LINES, -1);
@@ -815,6 +834,9 @@ gtk_tree_view_class_init (GtkTreeViewClass *class)
 
   gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0, "select_cursor_parent", 0);
 
+  gtk_binding_entry_add_signal (binding_set, GDK_s, GDK_CONTROL_MASK, "start_interactive_search", 0);
+
+  gtk_binding_entry_add_signal (binding_set, GDK_S, GDK_CONTROL_MASK, "start_interactive_search", 0);
 }
 
 static void
@@ -829,7 +851,7 @@ gtk_tree_view_init (GtkTreeView *tree_view)
 
   /* We need some padding */
   tree_view->priv->tab_offset += EXPANDER_EXTRA_PADDING;
-  
+
   tree_view->priv->n_columns = 0;
   tree_view->priv->header_height = 1;
   tree_view->priv->x_drag = 0;
@@ -967,7 +989,9 @@ gtk_tree_view_destroy (GtkObject *object)
   GtkWidget *search_dialog;
   GList *list;
 
- if (tree_view->priv->columns != NULL)
+  gtk_tree_view_stop_editing (tree_view);
+
+  if (tree_view->priv->columns != NULL)
     {
       list = tree_view->priv->columns;
       while (list)
@@ -1014,7 +1038,7 @@ gtk_tree_view_destroy (GtkObject *object)
       tree_view->priv->drag_dest_row = NULL;
     }
 
-  
+
   if (tree_view->priv->column_drop_func_data &&
       tree_view->priv->column_drop_func_data_destroy)
     {
@@ -1236,6 +1260,9 @@ gtk_tree_view_realize (GtkWidget *widget)
        }
       tree_view->priv->scroll_to_column = NULL;
     }
+
+  if (GTK_WIDGET_CLASS (parent_class)->map)
+    (* GTK_WIDGET_CLASS (parent_class)->map) (widget);
 }
 
 static void
@@ -1265,7 +1292,7 @@ gtk_tree_view_unrealize (GtkWidget *widget)
       gtk_timeout_remove (tree_view->priv->expand_collapse_timeout);
       tree_view->priv->expand_collapse_timeout = 0;
     }
-  
+
   for (list = tree_view->priv->columns; list; list = list->next)
     _gtk_tree_view_column_unrealize_button (GTK_TREE_VIEW_COLUMN (list->data));
 
@@ -1425,12 +1452,11 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
       GtkTreeViewChild *child = tmp_list->data;
       tmp_list = tmp_list->next;
 
-      /* totally ignore our childs allocation <-: */
+      /* totally ignore our childs requisition */
       allocation.x = child->x;
       allocation.y = child->y;
       allocation.width = child->width;
       allocation.height = child->height;
-
       gtk_widget_size_allocate (child->widget, &allocation);
     }
 
@@ -1487,12 +1513,17 @@ gtk_tree_view_button_press (GtkWidget      *widget,
   GdkRectangle background_area;
   GdkRectangle cell_area;
   gint vertical_separator;
+  gint horizontal_separator;
 
   g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
   tree_view = GTK_TREE_VIEW (widget);
-  gtk_widget_style_get (widget, "vertical_separator", &vertical_separator, NULL);
+  gtk_tree_view_stop_editing (tree_view);
+  gtk_widget_style_get (widget,
+                       "vertical_separator", &vertical_separator,
+                       "horizontal_separator", &horizontal_separator,
+                       NULL);
 
   if (event->window == tree_view->priv->bin_window)
     {
@@ -1528,7 +1559,7 @@ gtk_tree_view_button_press (GtkWidget      *widget,
        }
 
       /* find the node that was clicked */
-      new_y = ((gint)event->y<TREE_VIEW_HEADER_HEIGHT (tree_view))?TREE_VIEW_HEADER_HEIGHT (tree_view):(gint)event->y;
+      new_y = ((gint) event->y < TREE_VIEW_HEADER_HEIGHT (tree_view)) ? TREE_VIEW_HEADER_HEIGHT (tree_view) : (gint)event->y;
       y_offset = -_gtk_rbtree_find_offset (tree_view->priv->tree,
                                            TREE_WINDOW_Y_TO_RBTREE_Y (tree_view, new_y),
                                           &tree,
@@ -1541,8 +1572,8 @@ gtk_tree_view_button_press (GtkWidget      *widget,
       /* Get the path and the node */
       path = _gtk_tree_view_find_path (tree_view, tree, node);
       depth = gtk_tree_path_get_depth (path);
-      background_area.y = y_offset + event->y + vertical_separator;
-      background_area.height = GTK_RBNODE_GET_HEIGHT (node) - vertical_separator;
+      background_area.y = y_offset + event->y;
+      background_area.height = GTK_RBNODE_GET_HEIGHT (node);
       background_area.x = 0;
 
       /* Let the column have a chance at selecting it. */
@@ -1551,7 +1582,7 @@ gtk_tree_view_button_press (GtkWidget      *widget,
          GtkTreeIter iter;
          GtkCellEditable *cell_editable = NULL;
          /* FIXME: get the right flags */
-         guint flags = 0; 
+         guint flags = 0;
 
          column = list->data;
 
@@ -1559,18 +1590,6 @@ gtk_tree_view_button_press (GtkWidget      *widget,
            continue;
 
          background_area.width = column->width;
-         if (gtk_tree_view_is_expander_column (tree_view, column) &&
-              TREE_VIEW_DRAW_EXPANDERS(tree_view))
-           {
-             cell_area = background_area;
-             cell_area.x += depth*tree_view->priv->tab_offset;
-             cell_area.width -= depth*tree_view->priv->tab_offset;
-           }
-         else
-           {
-             cell_area = background_area;
-           }
-
          if ((background_area.x > (gint) event->x) ||
              (background_area.y > (gint) event->y) ||
              (background_area.x + background_area.width <= (gint) event->x) ||
@@ -1580,6 +1599,18 @@ gtk_tree_view_button_press (GtkWidget      *widget,
              continue;
            }
 
+         cell_area = background_area;
+         cell_area.width -= horizontal_separator;
+         cell_area.height -= vertical_separator;
+         cell_area.x += horizontal_separator/2;
+         cell_area.y += vertical_separator/2;
+         if (gtk_tree_view_is_expander_column (tree_view, column) &&
+              TREE_VIEW_DRAW_EXPANDERS(tree_view))
+           {
+             cell_area.x += depth*tree_view->priv->tab_offset;
+             cell_area.width -= depth*tree_view->priv->tab_offset;
+           }
+
          gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
          gtk_tree_view_column_cell_set_cell_data (column,
                                                   tree_view->priv->model,
@@ -1598,13 +1629,14 @@ gtk_tree_view_button_press (GtkWidget      *widget,
            {
              if (cell_editable != NULL)
                {
-                 gtk_tree_view_stop_editing (tree_view);
-                 gtk_tree_view_start_editing (tree_view,
-                                              column,
-                                              cell_editable,
-                                              &cell_area,
-                                              (GdkEvent *)event,
-                                              flags);
+                 gtk_tree_view_real_start_editing (tree_view,
+                                                   column,
+                                                   path,
+                                                   cell_editable,
+                                                   &cell_area,
+                                                   (GdkEvent *)event,
+                                                   flags);
+
                }
              g_free (path_string);
              gtk_tree_path_free (path);
@@ -1921,28 +1953,6 @@ ensure_unprelighted (GtkTreeView *tree_view)
   g_assert (tree_view->priv->prelight_node == NULL);
 }
 
-static void
-gtk_tree_view_ensure_focus_column (GtkTreeView *tree_view)
-{
-  GList *list;
-  if (tree_view->priv->focus_column != NULL &&
-      tree_view->priv->focus_column->visible)
-    return;
-
-  if (tree_view->priv->focus_column)
-    gtk_tree_view_column_cell_focus (tree_view->priv->focus_column, 0, TRUE);
-
-  for (list = tree_view->priv->columns; list; list = list->next)
-    {
-      GtkTreeViewColumn *column = list->data;
-
-      if (column->visible)
-       {
-         gtk_tree_view_column_cell_focus (column, 1, FALSE);
-         return;
-       }
-    }
-}
 
 
 
@@ -2057,7 +2067,7 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
                            NULL);
 
       width = expander_size;
-      
+
       /* Get x, y, width, height of arrow */
       if (reorder->left_column)
        {
@@ -2132,7 +2142,7 @@ gtk_tree_view_motion_draw_column_motion_arrow (GtkTreeView *tree_view)
                            NULL);
 
       width = expander_size;
-      
+
       /* Get x, y, width, height of arrow */
       width = width/2; /* remember, the arrow only takes half the available width */
       gdk_window_get_origin (widget->window, &x, &y);
@@ -2431,17 +2441,23 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
   GtkTreePath *drag_dest_path;
   GList *last_column;
   gint vertical_separator;
+  gint horizontal_separator;
+  gboolean allow_rules;
 
   g_return_val_if_fail (GTK_IS_TREE_VIEW (widget), FALSE);
 
   tree_view = GTK_TREE_VIEW (widget);
-  gtk_widget_style_get (widget, "vertical_separator", &vertical_separator, NULL);
+  gtk_widget_style_get (widget,
+                       "horizontal_separator", &horizontal_separator,
+                       "vertical_separator", &vertical_separator,
+                       "allow_rules", &allow_rules,
+                       NULL);
 
   if (tree_view->priv->tree == NULL)
     return TRUE;
 
   gtk_tree_view_check_dirty_and_clean (GTK_TREE_VIEW (widget));
-  gtk_tree_view_ensure_focus_column (GTK_TREE_VIEW (widget));
+
   /* we want to account for a potential HEADER offset.  That is, if the header
    * exists, we want to offset our event by its height to find the right node.
    */
@@ -2516,7 +2532,7 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
         flags |= GTK_CELL_RENDERER_SELECTED;
 
       parity = _gtk_rbtree_node_find_parity (tree, node);
-      
+
       for (list = tree_view->priv->columns; list; list = list->next)
        {
          GtkTreeViewColumn *column = list->data;
@@ -2550,17 +2566,15 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
 
           cell_area = background_area;
           cell_area.y += vertical_separator / 2;
+          cell_area.x += horizontal_separator / 2;
           cell_area.height -= vertical_separator;
+         cell_area.width -= horizontal_separator;
 
           /* Select the detail for drawing the cell.  relevant
            * factors are parity, sortedness, and whether to
            * display rules.
            */
-
-          /* FIXME when we have style properties, clean this up.
-           */
-
-          if (tree_view->priv->has_rules)
+          if (allow_rules && tree_view->priv->has_rules)
             {
               if (flags & GTK_CELL_RENDERER_SORTED)
                 {
@@ -2653,8 +2667,9 @@ gtk_tree_view_bin_expose (GtkWidget      *widget,
                                                flags);
            }
          if (node == cursor &&
-             GTK_WIDGET_HAS_FOCUS (widget) &&
-             column == tree_view->priv->focus_column)
+             ((column == tree_view->priv->focus_column &&
+               GTK_WIDGET_HAS_FOCUS (widget)) ||
+              (column == tree_view->priv->edited_column)))
            {
              gtk_tree_view_column_cell_draw_focus (column,
                                                    event->window,
@@ -2806,7 +2821,6 @@ gtk_tree_view_key_press (GtkWidget   *widget,
                         GdkEventKey *event)
 {
   GtkTreeView *tree_view = (GtkTreeView *) widget;
-  gint retval;
 
   if (GTK_TREE_VIEW_FLAG_SET (tree_view, GTK_TREE_VIEW_IN_COLUMN_DRAG))
     {
@@ -2818,12 +2832,7 @@ gtk_tree_view_key_press (GtkWidget   *widget,
       return TRUE;
     }
 
-  retval = (* GTK_WIDGET_CLASS (parent_class)->key_press_event) (widget, event);
-
-  if (! retval)
-    gtk_tree_view_interactive_search (tree_view, event);
-
-  return retval;
+  return (* GTK_WIDGET_CLASS (parent_class)->key_press_event) (widget, event);
 }
 
 /* FIXME Is this function necessary? Can I get an enter_notify event
@@ -2892,7 +2901,7 @@ gtk_tree_view_leave_notify (GtkWidget        *widget,
                                    NULL);
 
   ensure_unprelighted (tree_view);
-  
+
 return TRUE;
 }
 
@@ -2932,8 +2941,7 @@ gtk_tree_view_focus_out (GtkWidget     *widget,
   /* destroy interactive search dialog */
   search_dialog = gtk_object_get_data (GTK_OBJECT (widget), "search-dialog");
   if (search_dialog)
-    gtk_tree_view_search_dialog_destroy (search_dialog,
-                                                    GTK_TREE_VIEW (widget));
+    gtk_tree_view_search_dialog_destroy (search_dialog, GTK_TREE_VIEW (widget));
   return FALSE;
 }
 
@@ -3178,7 +3186,7 @@ open_row_timeout (gpointer data)
   gboolean result = FALSE;
 
   GDK_THREADS_ENTER ();
-  
+
   gtk_tree_view_get_drag_dest_row (tree_view,
                                    &dest_path,
                                    &pos);
@@ -3196,10 +3204,10 @@ open_row_timeout (gpointer data)
     {
       if (dest_path)
         gtk_tree_path_free (dest_path);
-      
+
       result = TRUE;
     }
-  
+
   GDK_THREADS_LEAVE ();
 
   return result;
@@ -4017,16 +4025,6 @@ gtk_tree_view_header_focus (GtkTreeView      *tree_view,
   return (focus_child != NULL);
 }
 
-/* We make the assumption that if container->focus_child != NULL, the focus must
- * be in the header.  For now, this is accurate.  It may not be in the future.
- */
-
-/* The sordid relationship between focus_column and scroll_column:
- *
- * The focus_column represents the column that currently has keyboard focus, and
- * is used when navigating columns by keyboard.  scroll_column is used for
- * handling scrolling by keyboard, such that in cases.
- */
 static gint
 gtk_tree_view_focus (GtkWidget        *widget,
                     GtkDirectionType  direction)
@@ -4046,6 +4044,7 @@ gtk_tree_view_focus (GtkWidget        *widget,
 
   focus_child = container->focus_child;
 
+  gtk_tree_view_stop_editing (GTK_TREE_VIEW (widget));
   /* Case 1.  Headers currently have focus. */
   if (focus_child)
     {
@@ -4194,7 +4193,7 @@ gtk_tree_view_real_move_cursor (GtkTreeView       *tree_view,
 
   if (tree_view->priv->tree == NULL)
     return;
-
+  gtk_tree_view_stop_editing (tree_view);
   GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
   gtk_widget_grab_focus (GTK_WIDGET (tree_view));
 
@@ -4219,10 +4218,10 @@ gtk_tree_view_real_move_cursor (GtkTreeView       *tree_view,
     }
 }
 
-static void           
-gtk_tree_view_put (GtkTreeView *tree_view, 
-                  GtkWidget   *child_widget, 
-                  gint         x, 
+static void
+gtk_tree_view_put (GtkTreeView *tree_view,
+                  GtkWidget   *child_widget,
+                  gint         x,
                   gint         y,
                   gint         width,
                   gint         height)
@@ -4231,7 +4230,7 @@ gtk_tree_view_put (GtkTreeView *tree_view,
 
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
   g_return_if_fail (GTK_IS_WIDGET (child_widget));
-  
+
   child = g_new (GtkTreeViewChild, 1);
 
   child->widget = child_widget;
@@ -4241,7 +4240,7 @@ gtk_tree_view_put (GtkTreeView *tree_view,
   child->height = height;
 
   tree_view->priv->children = g_list_append (tree_view->priv->children, child);
-  
+
   if (GTK_WIDGET_REALIZED (tree_view))
     gtk_widget_set_parent_window (child->widget, tree_view->priv->bin_window);
 
@@ -4334,6 +4333,7 @@ gtk_tree_view_row_changed (GtkTreeModel *model,
     {
       _gtk_rbtree_node_set_height (tree, node, height + vertical_separator);
       gtk_widget_queue_resize (GTK_WIDGET (data));
+      _gtk_tree_view_update_size (tree_view);
       goto done;
     }
   if (dirty_marked)
@@ -4542,14 +4542,14 @@ gtk_tree_view_row_deleted (GtkTreeModel *model,
 
   g_return_if_fail (path != NULL);
 
+  gtk_tree_row_reference_deleted (G_OBJECT (data), path);
+
   if (_gtk_tree_view_find_node (tree_view, path, &tree, &node))
     return;
 
   if (tree == NULL)
     return;
 
-  gtk_tree_row_reference_deleted (G_OBJECT (data), path);
-
   /* Change the selection */
   selection_changed = GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED);
 
@@ -4572,7 +4572,7 @@ gtk_tree_view_row_deleted (GtkTreeModel *model,
       GTK_RBNODE_UNSET_FLAG (tree_view->priv->expanded_collapsed_node, GTK_RBNODE_IS_SEMI_EXPANDED);
       tree_view->priv->expanded_collapsed_node = NULL;
     }
-  
+
   if (tree_view->priv->destroy_count_func)
     {
       gint child_count = 0;
@@ -4801,9 +4801,9 @@ gtk_tree_view_insert_iter_height (GtkTreeView *tree_view,
   GList *list;
   gint max_height = 0;
   gint vertical_separator;
-  
+
   gtk_widget_style_get (GTK_WIDGET (tree_view),        "vertical_separator", &vertical_separator, NULL);
-  
+
   /* do stuff with node */
   for (list = tree_view->priv->columns; list; list = list->next)
     {
@@ -4890,10 +4890,13 @@ gtk_tree_view_calc_size (GtkTreeView *tree_view,
   GtkTreeViewColumn *column;
   gint max_height;
   gint vertical_separator;
-  
+  gint horizontal_separator;
   TREE_VIEW_INTERNAL_ASSERT_VOID (tree != NULL);
 
-  gtk_widget_style_get (GTK_WIDGET (tree_view),        "vertical_separator", &vertical_separator, NULL);
+  gtk_widget_style_get (GTK_WIDGET (tree_view),
+                       "vertical_separator", &vertical_separator,
+                       "horizontal_separator", &horizontal_separator,
+                       NULL);
 
   temp = tree->root;
   while (temp->left != tree->nil)
@@ -4928,9 +4931,9 @@ gtk_tree_view_calc_size (GtkTreeView *tree_view,
          if (gtk_tree_view_is_expander_column (tree_view, column) &&
               TREE_VIEW_DRAW_EXPANDERS (tree_view))
             _gtk_tree_view_column_set_width (column,
-                                            MAX (column->width, depth * tree_view->priv->tab_offset + width));
+                                            MAX (column->width, depth * tree_view->priv->tab_offset + width + horizontal_separator));
          else
-            _gtk_tree_view_column_set_width (column, MAX (column->width, width));
+            _gtk_tree_view_column_set_width (column, MAX (column->width, width + horizontal_separator));
        }
 
       _gtk_rbtree_node_set_height (tree, temp, max_height);
@@ -4954,7 +4957,12 @@ gtk_tree_view_discover_dirty_iter (GtkTreeView *tree_view,
   GList *list;
   gboolean retval = FALSE;
   gint tmpheight;
-  
+  gint horizontal_separator;
+
+  gtk_widget_style_get (GTK_WIDGET (tree_view),
+                       "horizontal_separator", &horizontal_separator,
+                       NULL);
+
   if (height)
     *height = 0;
 
@@ -4966,12 +4974,11 @@ gtk_tree_view_discover_dirty_iter (GtkTreeView *tree_view,
        continue;
       if (!column->visible)
        continue;
-      
+
       gtk_tree_view_column_cell_set_cell_data (column, tree_view->priv->model, iter,
                                               GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_PARENT),
                                               node->children?TRUE:FALSE);
 
-
       if (height)
        {
          gtk_tree_view_column_cell_get_size (column,
@@ -4989,7 +4996,7 @@ gtk_tree_view_discover_dirty_iter (GtkTreeView *tree_view,
       if (gtk_tree_view_is_expander_column (tree_view, column) &&
           TREE_VIEW_DRAW_EXPANDERS (tree_view))
        {
-         if (depth * tree_view->priv->tab_offset + width > column->width)
+         if (depth * tree_view->priv->tab_offset + horizontal_separator + width > column->requested_width)
            {
              gtk_tree_view_column_cell_set_dirty (column);
              retval = TRUE;
@@ -4997,7 +5004,7 @@ gtk_tree_view_discover_dirty_iter (GtkTreeView *tree_view,
        }
       else
        {
-         if (width > column->width)
+         if (horizontal_separator + width > column->requested_width)
            {
              gtk_tree_view_column_cell_set_dirty (column);
              retval = TRUE;
@@ -5045,7 +5052,7 @@ gtk_tree_view_discover_dirty (GtkTreeView *tree_view,
       gtk_tree_view_discover_dirty_iter (tree_view,
                                         iter,
                                         depth,
-                                        FALSE,
+                                        NULL,
                                         temp);
       if (gtk_tree_model_iter_children (tree_view->priv->model, &child, iter) &&
          temp->children != NULL)
@@ -5059,8 +5066,8 @@ gtk_tree_view_discover_dirty (GtkTreeView *tree_view,
 /**
  * gtk_tree_view_check_dirty_and_clean:
  * @tree_view: A #GtkTreeView
- * 
- * Does all the actual sizing for 
+ *
+ * Does all the actual sizing for
  **/
 static void
 gtk_tree_view_check_dirty_and_clean (GtkTreeView *tree_view)
@@ -5141,10 +5148,24 @@ gtk_tree_view_clamp_node_visible (GtkTreeView *tree_view,
 
 }
 
-/* This function could be more efficient.
- * I'll optimize it if profiling seems to imply that
- * it's important
- */
+static void
+gtk_tree_view_clamp_column_visible (GtkTreeView       *tree_view,
+                                   GtkTreeViewColumn *column)
+{
+  if (column == NULL)
+    return;
+  if ((tree_view->priv->hadjustment->value + tree_view->priv->hadjustment->page_size) <
+      (column->button->allocation.x + column->button->allocation.width))
+    gtk_adjustment_set_value (tree_view->priv->hadjustment,
+                             column->button->allocation.x + column->button->allocation.width -
+                             tree_view->priv->hadjustment->page_size);
+  else if (tree_view->priv->hadjustment->value > column->button->allocation.x)
+    gtk_adjustment_set_value (tree_view->priv->hadjustment,
+                             column->button->allocation.x);
+}
+
+/* This function could be more efficient.  I'll optimize it if profiling seems
+ * to imply that it is important */
 GtkTreePath *
 _gtk_tree_view_find_path (GtkTreeView *tree_view,
                          GtkRBTree   *tree,
@@ -5563,9 +5584,9 @@ gtk_tree_view_queue_draw_arrow (GtkTreeView      *tree_view,
   if (clip_rect)
     {
       GdkRectangle new_rect;
-      
+
       gdk_rectangle_intersect (clip_rect, &rect, &new_rect);
-      
+
       gdk_window_invalidate_rect (tree_view->priv->bin_window, &new_rect, TRUE);
     }
   else
@@ -5635,7 +5656,7 @@ gtk_tree_view_draw_arrow (GtkTreeView *tree_view,
   gint vertical_separator;
   gint expander_size;
   GtkExpanderStyle expander_style;
-  
+
   gtk_widget_style_get (GTK_WIDGET (tree_view),
                        "vertical_separator", &vertical_separator,
                        "expander_size", &expander_size,
@@ -5749,6 +5770,18 @@ gtk_tree_view_focus_to_cursor (GtkTreeView *tree_view)
        gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE);
     }
   gtk_tree_path_free (cursor_path);
+  if (tree_view->priv->focus_column == NULL)
+    {
+      GList *list;
+      for (list = tree_view->priv->columns; list; list = list->next)
+       {
+         if (GTK_TREE_VIEW_COLUMN (list->data)->visible)
+           {
+             tree_view->priv->focus_column = GTK_TREE_VIEW_COLUMN (list->data);
+             break;
+           }
+       }
+    }
 }
 
 static void
@@ -5829,9 +5862,7 @@ gtk_tree_view_move_cursor_page_up_down (GtkTreeView *tree_view,
   _gtk_rbtree_find_offset (tree_view->priv->tree, y, &cursor_tree, &cursor_node);
   cursor_path = _gtk_tree_view_find_path (tree_view, cursor_tree, cursor_node);
   g_return_if_fail (cursor_path != NULL);
-  gtk_tree_view_real_set_cursor (tree_view,
-                                cursor_path,
-                                TRUE);
+  gtk_tree_view_real_set_cursor (tree_view, cursor_path, TRUE);
 }
 
 static void
@@ -5870,19 +5901,19 @@ gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view,
            break;
        }
     }
-      
+
   while (list)
     {
       column = list->data;
       if (column->visible == FALSE)
        goto loop_end;
 
-      gtk_tree_view_column_cell_set_cell_data  (column,
-                                               tree_view->priv->model,
-                                               &iter,
-                                               GTK_RBNODE_FLAG_SET (cursor_node, GTK_RBNODE_IS_PARENT),
-                                               cursor_node->children?TRUE:FALSE);
-      if (gtk_tree_view_column_cell_focus (column, count, FALSE))
+      gtk_tree_view_column_cell_set_cell_data (column,
+                                              tree_view->priv->model,
+                                              &iter,
+                                              GTK_RBNODE_FLAG_SET (cursor_node, GTK_RBNODE_IS_PARENT),
+                                              cursor_node->children?TRUE:FALSE);
+      if (gtk_tree_view_column_cell_focus (column, count))
        {
          tree_view->priv->focus_column = column;
          found_column = TRUE;
@@ -5901,9 +5932,8 @@ gtk_tree_view_move_cursor_left_right (GtkTreeView *tree_view,
                                     cursor_tree,
                                     cursor_node,
                                     NULL);
-      return;
     }
-  g_print ("scroll now!\n");
+  gtk_tree_view_clamp_column_visible (tree_view, tree_view->priv->focus_column);
 }
 
 static void
@@ -5959,8 +5989,8 @@ gtk_tree_view_real_select_cursor_row (GtkTreeView *tree_view)
   GtkRBNode *cursor_node = NULL;
   GtkTreePath *cursor_path = NULL;
   GdkModifierType state = 0;
-
   cursor_path = NULL;
+
   if (tree_view->priv->cursor)
     cursor_path = gtk_tree_row_reference_get_path (tree_view->priv->cursor);
 
@@ -5969,12 +5999,22 @@ gtk_tree_view_real_select_cursor_row (GtkTreeView *tree_view)
 
   _gtk_tree_view_find_node (tree_view, cursor_path,
                            &cursor_tree, &cursor_node);
+
   if (cursor_tree == NULL)
     {
       gtk_tree_path_free (cursor_path);
       return;
     }
 
+  if (tree_view->priv->focus_column)
+    {
+      if (gtk_tree_view_start_editing (tree_view, cursor_path))
+       {
+         gtk_tree_path_free (cursor_path);
+         return;
+       }
+    }
+
   gtk_get_current_event_state (&state);
   _gtk_tree_selection_internal_select_node (tree_view->priv->selection,
                                            cursor_node,
@@ -5985,7 +6025,9 @@ gtk_tree_view_real_select_cursor_row (GtkTreeView *tree_view)
   gtk_tree_view_clamp_node_visible (tree_view, cursor_tree, cursor_node);
 
   gtk_widget_grab_focus (GTK_WIDGET (tree_view));
-  gtk_tree_view_queue_draw_path (tree_view, cursor_path, NULL);
+  gtk_tree_view_queue_draw_node (tree_view, cursor_tree, cursor_node, NULL);
+  gtk_tree_view_row_activated (tree_view, cursor_path, tree_view->priv->focus_column);
+
   gtk_tree_path_free (cursor_path);
 }
 
@@ -6096,6 +6138,58 @@ gtk_tree_view_real_select_cursor_parent (GtkTreeView *tree_view)
   gtk_tree_path_free (cursor_path);
 }
 
+static void
+gtk_tree_view_real_start_interactive_search (GtkTreeView *tree_view)
+{
+  GtkWidget *window;
+  GtkWidget *entry;
+
+  if (tree_view->priv->enable_search == FALSE ||
+      tree_view->priv->search_column < 0)
+    return;
+
+  /* set up window */
+  window = gtk_window_new (GTK_WINDOW_POPUP);
+  gtk_window_set_title (GTK_WINDOW (window), "search dialog");
+  gtk_container_set_border_width (GTK_CONTAINER (window), 3);
+  gtk_window_set_modal (GTK_WINDOW (window), TRUE);
+  gtk_signal_connect
+    (GTK_OBJECT (window), "delete_event",
+     GTK_SIGNAL_FUNC (gtk_tree_view_search_delete_event),
+     tree_view);
+  gtk_signal_connect
+    (GTK_OBJECT (window), "key_press_event",
+     GTK_SIGNAL_FUNC (gtk_tree_view_search_key_press_event),
+     tree_view);
+  gtk_signal_connect
+    (GTK_OBJECT (window), "button_press_event",
+     GTK_SIGNAL_FUNC (gtk_tree_view_search_button_press_event),
+     tree_view);
+
+  /* add entry */
+  entry = gtk_entry_new ();
+  gtk_widget_show (entry);
+  gtk_signal_connect
+    (GTK_OBJECT (entry), "changed",
+     GTK_SIGNAL_FUNC (gtk_tree_view_search_init),
+     tree_view);
+  gtk_container_add (GTK_CONTAINER (window), entry);
+
+  /* done, show it */
+  tree_view->priv->search_dialog_position_func (tree_view, window);
+  gtk_widget_show_all (window);
+  gtk_widget_grab_focus (entry);
+
+  /* position window */
+
+  gtk_object_set_data (GTK_OBJECT (window), "text",
+                       gtk_entry_get_text (GTK_ENTRY (entry)));
+  gtk_object_set_data (GTK_OBJECT (tree_view), "search-dialog", window);
+
+  /* search first matching iter */
+  gtk_tree_view_search_init (entry, tree_view);
+}
+
 void
 _gtk_tree_view_update_size (GtkTreeView *tree_view)
 {
@@ -6982,7 +7076,7 @@ gtk_tree_view_move_column_after (GtkTreeView       *tree_view,
  * gtk_tree_view_set_expander_column:
  * @tree_view: A #GtkTreeView
  * @column: NULL, or the column to draw the expander arrow at.
- * 
+ *
  * Sets the column to draw the expander arrow at. It must be in @tree_view.  If
  * @column is %NULL, then the expander arrow is fixed at the first column.
  **/
@@ -7204,8 +7298,6 @@ gtk_tree_view_row_activated (GtkTreeView       *tree_view,
 {
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
 
-  /* FIXME: Actually activate the path internally, not just emit the signal */
-  /*  g_warning ("FIXME: Actually activate the path internally, not just emit the signal\n"); */
   g_signal_emit (G_OBJECT(tree_view), tree_view_signals[ROW_ACTIVATED], 0, path, column);
 }
 
@@ -7277,13 +7369,13 @@ expand_collapse_timeout (gpointer data)
   gboolean redraw;
 
   GDK_THREADS_ENTER ();
-  
+
   redraw = FALSE;
   expanding = TRUE;
 
   node = tree_view->priv->expanded_collapsed_node;
   tree = tree_view->priv->expanded_collapsed_tree;
-  
+
   if (node->children == NULL)
     expanding = FALSE;
 
@@ -7295,7 +7387,7 @@ expand_collapse_timeout (gpointer data)
          GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_EXPANDED);
 
          redraw = TRUE;
-         
+
        }
       else if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SEMI_EXPANDED))
        {
@@ -7417,7 +7509,7 @@ gtk_tree_view_real_expand_row (GtkTreeView *tree_view,
 
   if (tree_view->priv->expand_collapse_timeout)
     gtk_timeout_remove (tree_view->priv->expand_collapse_timeout);
-  
+
   if (tree_view->priv->expanded_collapsed_node != NULL)
     {
       GTK_RBNODE_UNSET_FLAG (tree_view->priv->expanded_collapsed_node, GTK_RBNODE_IS_SEMI_EXPANDED);
@@ -7427,7 +7519,7 @@ gtk_tree_view_real_expand_row (GtkTreeView *tree_view,
   tree_view->priv->expand_collapse_timeout = gtk_timeout_add (50, expand_collapse_timeout, tree_view);
   tree_view->priv->expanded_collapsed_node = node;
   tree_view->priv->expanded_collapsed_tree = tree;
-  
+
   GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_COLLAPSED);
 
   if (GTK_WIDGET_MAPPED (tree_view))
@@ -7497,7 +7589,7 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
 
   /* if the prelighted node is a child of us, we want to unprelight it.  We have
    * a chance to prelight the correct node below */
-  
+
   if (tree_view->priv->prelight_tree)
     {
       GtkRBTree *parent_tree;
@@ -7528,7 +7620,7 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
       if (gtk_tree_view_column_get_sizing (column) == GTK_TREE_VIEW_COLUMN_AUTOSIZE)
        gtk_tree_view_column_cell_set_dirty (column);
     }
-  
+
   if (tree_view->priv->destroy_count_func)
     {
       GtkTreePath *child_path;
@@ -7559,7 +7651,7 @@ gtk_tree_view_real_collapse_row (GtkTreeView *tree_view,
   tree_view->priv->expanded_collapsed_tree = tree;
 
   GTK_RBNODE_SET_FLAG (node, GTK_RBNODE_IS_SEMI_EXPANDED);
-  
+
   if (GTK_WIDGET_MAPPED (tree_view))
     {
       gtk_widget_queue_draw (GTK_WIDGET (tree_view));
@@ -7713,9 +7805,9 @@ gtk_tree_view_map_expanded_rows (GtkTreeView            *tree_view,
  * gtk_tree_view_row_expanded:
  * @tree_view: A #GtkTreeView.
  * @path: A #GtkTreePath to test expansion state.
- * 
+ *
  * Returns TRUE if the node pointed to by @path is expanded in @tree_view.
- * 
+ *
  * Return value: TRUE if #path is expanded.
  **/
 gboolean
@@ -7837,21 +7929,45 @@ gtk_tree_view_real_set_cursor (GtkTreeView     *tree_view,
  * gtk_tree_view_set_cursor:
  * @tree_view: A #GtkTreeView
  * @path: A #GtkTreePath
+ * @focus_column: A #GtkTreeViewColumn, or NULL
+ * @start_editing: %TRUE if the specified cell should start being edited.
  *
  * Sets the current keyboard focus to be at @path, and selects it.  This is
  * useful when you want to focus the user's attention on a particular row.  If
- * you want to give the user keyboard focus in the tree_view, you should use
- * this function to set the correct path, and gtk_widget_grab_focus (GTK_WIDGET
- * (tree_view)) to actually give focus to the @tree_view.
+ * @column is not %NULL, then focus is given to the column specified by it.
+ * Additionally, if @column is specified, and @start_editing is %TRUE, then
+ * editing should be started in the specified cell.  Keyboard focus is given to
+ * the widget after this is called.
  **/
 void
-gtk_tree_view_set_cursor (GtkTreeView *tree_view,
-                         GtkTreePath *path)
+gtk_tree_view_set_cursor (GtkTreeView       *tree_view,
+                         GtkTreePath       *path,
+                         GtkTreeViewColumn *focus_column,
+                         gboolean           start_editing)
 {
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
   g_return_if_fail (path != NULL);
+  if (focus_column)
+    g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (focus_column));
 
   gtk_tree_view_real_set_cursor (tree_view, path, TRUE);
+
+  gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+  if (focus_column && focus_column->visible)
+    {
+      GList *list;
+      gboolean column_in_tree = FALSE;
+
+      for (list = tree_view->priv->columns; list; list = list->next)
+       if (list->data == focus_column)
+         {
+           column_in_tree = TRUE;
+           break;
+         }
+      g_return_if_fail (column_in_tree);
+      if (start_editing)
+       gtk_tree_view_start_editing (tree_view, path);
+    }
 }
 
 
@@ -7990,12 +8106,13 @@ gtk_tree_view_get_path_at_pos (GtkTreeView        *tree_view,
  *
  * Fills the bounding rectangle in tree window coordinates for the cell at the
  * row specified by @path and the column specified by @column.  If @path is
- * %NULL, the y and height fields of the rectangle will be filled with 0. If
- * @column is %NULL, the x and width fields will be filled with 0.  The sum of
- * all cell rects does not cover the entire tree; there are extra pixels in
- * between rows, for example. The returned rectangle is equivalent to the
- * @cell_area passed to gtk_cell_renderer_render().  This function is only valid
- * if #tree_view is realized.
+ * %NULL, or points to a path not currently displayed, the y and height fields
+ * of the rectangle will be filled with 0. If @column is %NULL, the x and width
+ * fields will be filled with 0.  The sum of all cell rects does not cover the
+ * entire tree; there are extra pixels in between rows, for example. The
+ * returned rectangle is equivalent to the @cell_area passed to
+ * gtk_cell_renderer_render().  This function is only valid if #tree_view is
+ * realized.
  **/
 void
 gtk_tree_view_get_cell_area (GtkTreeView        *tree_view,
@@ -8006,6 +8123,7 @@ gtk_tree_view_get_cell_area (GtkTreeView        *tree_view,
   GtkRBTree *tree = NULL;
   GtkRBNode *node = NULL;
   gint vertical_separator;
+  gint horizontal_separator;
 
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
   g_return_if_fail (column == NULL || GTK_IS_TREE_VIEW_COLUMN (column));
@@ -8013,37 +8131,40 @@ gtk_tree_view_get_cell_area (GtkTreeView        *tree_view,
   g_return_if_fail (!column || column->tree_view == (GtkWidget *) tree_view);
   g_return_if_fail (GTK_WIDGET_REALIZED (tree_view));
 
-  gtk_widget_style_get (GTK_WIDGET (tree_view), "vertical_separator", &vertical_separator, NULL);
+  gtk_widget_style_get (GTK_WIDGET (tree_view),
+                       "vertical_separator", &vertical_separator,
+                       "horizontal_separator", &horizontal_separator,
+                       NULL);
 
   rect->x = 0;
   rect->y = 0;
   rect->width = 0;
   rect->height = 0;
 
+  if (column)
+    {
+      rect->x = column->button->allocation.x + horizontal_separator/2;
+      rect->width = column->button->allocation.width - horizontal_separator;
+    }
+
   if (path)
     {
       /* Get vertical coords */
+      if (_gtk_tree_view_find_node (tree_view, path, &tree, &node) &&
+         tree != NULL)
+       return;
 
-      _gtk_tree_view_find_node (tree_view, path, &tree, &node);
-
-      if (tree == NULL)
-        {
-          g_warning (G_STRLOC": no row corresponding to path");
-          return;
-        }
-
-      /* Remember that the rbtree stores node height including the vertical
-       * separator, see comment at top of file.
-       */
       rect->y = CELL_FIRST_PIXEL (tree_view, tree, node, vertical_separator);
-
       rect->height = CELL_HEIGHT (node, vertical_separator);
-    }
 
-  if (column)
-    {
-      rect->x = column->button->allocation.x;
-      rect->width = column->button->allocation.width;
+      if (gtk_tree_view_is_expander_column (tree_view, column) &&
+         TREE_VIEW_DRAW_EXPANDERS (tree_view))
+       {
+         gint depth = gtk_tree_path_get_depth (path) - 1;
+         rect->x += depth * tree_view->priv->tab_offset;
+         rect->width -= depth * tree_view->priv->tab_offset;
+         rect->width = MAX (rect->width, 0);
+       }
     }
 }
 
@@ -8054,17 +8175,16 @@ gtk_tree_view_get_cell_area (GtkTreeView        *tree_view,
  * @column: a #GtkTreeViewColumn for the column, or %NULL to get only vertical coordiantes
  * @rect: rectangle to fill with cell background rect
  *
- * Fills the bounding rectangle in tree window coordinates for the
- * cell at the row specified by @path and the column specified by
- * @column.  If @path is %NULL, the y and height fields of the
- * rectangle will be filled with 0. If @column is %NULL, the x and
- * width fields will be filled with 0.  The returned rectangle is
- * equivalent to the @background_area passed to
- * gtk_cell_renderer_render().  These background areas tile to cover
- * the entire tree window (except for the area used for header
- * buttons). Contrast with the cell_area, returned by
- * gtk_tree_view_get_cell_area(), which returns only the cell itself,
- * excluding surrounding borders and the tree expander area.
+ * Fills the bounding rectangle in tree window coordinates for the cell at the
+ * row specified by @path and the column specified by @column.  If @path is
+ * %NULL, or points to a node not found in the tree, the y and height fields of
+ * the rectangle will be filled with 0. If @column is %NULL, the x and width
+ * fields will be filled with 0.  The returned rectangle is equivalent to the
+ * @background_area passed to gtk_cell_renderer_render().  These background
+ * areas tile to cover the entire tree window (except for the area used for
+ * header buttons). Contrast with the cell_area, returned by
+ * gtk_tree_view_get_cell_area(), which returns only the cell itself, excluding
+ * surrounding borders and the tree expander area.
  *
  **/
 void
@@ -8089,13 +8209,9 @@ gtk_tree_view_get_background_area (GtkTreeView        *tree_view,
     {
       /* Get vertical coords */
 
-      _gtk_tree_view_find_node (tree_view, path, &tree, &node);
-
-      if (tree == NULL)
-        {
-          g_warning (G_STRLOC": no row corresponding to path");
-          return;
-        }
+      if (_gtk_tree_view_find_node (tree_view, path, &tree, &node) &&
+         tree != NULL)
+       return;
 
       rect->y = BACKGROUND_FIRST_PIXEL (tree_view, tree, node);
 
@@ -8163,14 +8279,9 @@ gtk_tree_view_widget_to_tree_coords (GtkTreeView *tree_view,
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
 
   if (tx)
-    {
-      *tx = wx + tree_view->priv->hadjustment->value;
-    }
-
+    *tx = wx + tree_view->priv->hadjustment->value;
   if (ty)
-    {
-      *ty = wy + tree_view->priv->vadjustment->value;
-    }
+    *ty = wy + tree_view->priv->vadjustment->value;
 }
 
 /**
@@ -8195,14 +8306,9 @@ gtk_tree_view_tree_to_widget_coords (GtkTreeView *tree_view,
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
 
   if (wx)
-    {
-      *wx = tx - tree_view->priv->hadjustment->value;
-    }
-
+    *wx = tx - tree_view->priv->hadjustment->value;
   if (wy)
-    {
-      *wy = ty - tree_view->priv->vadjustment->value;
-    }
+    *wy = ty - tree_view->priv->vadjustment->value;
 }
 
 
@@ -8585,7 +8691,7 @@ gtk_tree_view_create_row_drag_icon (GtkTreeView  *tree_view,
  * @func: Function to be called when a view row is destroyed, or NULL
  * @data: User data to be passed to @func, or NULL
  * @destroy: Destroy notifier for @data, or NULL
- * 
+ *
  * This function should almost never be used.  It is meant for private use by
  * ATK for determining the number of visible children that are removed when the
  * user collapses a row, or a row is deleted.
@@ -8608,7 +8714,7 @@ gtk_tree_view_set_destroy_count_func (GtkTreeView             *tree_view,
 
 
 /*
- * Interactive search 
+ * Interactive search
  */
 
 /**
@@ -8657,7 +8763,7 @@ gint
 gtk_tree_view_get_search_column (GtkTreeView *tree_view)
 {
   g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), 0);
-  
+
   return (tree_view->priv->search_column);
 }
 
@@ -8680,7 +8786,7 @@ gtk_tree_view_set_search_column (GtkTreeView *tree_view,
     return;
 
   tree_view->priv->search_column = column;
-  
+
 }
 
 /**
@@ -8732,7 +8838,7 @@ gtk_tree_view_search_dialog_destroy (GtkWidget   *search_dialog,
 {
   /* remove data from tree_view */
   gtk_object_remove_data (GTK_OBJECT (tree_view), "search-dialog");
-  
+
   gtk_widget_destroy (search_dialog);
 }
 
@@ -8756,84 +8862,6 @@ gtk_tree_view_search_position_func (GtkTreeView *tree_view,
                   tree_y + tree_height);
 }
 
-static void
-gtk_tree_view_interactive_search (GtkTreeView *tree_view,
-                                 GdkEventKey *event)
-{
-  GtkWidget *window;
-  GtkWidget *entry;
-  
-  g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
-  switch (event->keyval)
-    {
-    case GDK_Shift_L:
-    case GDK_Shift_R:
-    case GDK_Control_L:
-    case GDK_Control_R:
-    case GDK_Caps_Lock:
-    case GDK_Shift_Lock:
-    case GDK_Meta_L:
-    case GDK_Meta_R:
-    case GDK_Alt_L:
-    case GDK_Alt_R:
-    case GDK_Super_L:
-    case GDK_Super_R:
-    case GDK_Hyper_L:
-    case GDK_Hyper_R:
-    case GDK_Mode_switch:
-      return;
-    default:
-      break;
-    }
-
-  if (tree_view->priv->enable_search == FALSE ||
-      tree_view->priv->search_column < 0)
-    return;
-
-  /* set up window */
-  window = gtk_window_new (GTK_WINDOW_POPUP);
-  gtk_window_set_title (GTK_WINDOW (window), "search dialog");
-  gtk_container_set_border_width (GTK_CONTAINER (window), 3);
-  gtk_window_set_modal (GTK_WINDOW (window), TRUE);
-  gtk_signal_connect 
-    (GTK_OBJECT (window), "delete_event",
-     GTK_SIGNAL_FUNC (gtk_tree_view_search_delete_event),
-     tree_view);
-  gtk_signal_connect 
-    (GTK_OBJECT (window), "key_press_event",
-     GTK_SIGNAL_FUNC (gtk_tree_view_search_key_press_event),
-     tree_view);
-  gtk_signal_connect
-    (GTK_OBJECT (window), "button_press_event",
-     GTK_SIGNAL_FUNC (gtk_tree_view_search_button_press_event),
-     tree_view);
-
-  /* add entry */
-  entry = gtk_entry_new ();
-  gtk_widget_show (entry);
-  gtk_signal_connect
-    (GTK_OBJECT (entry), "changed",
-     GTK_SIGNAL_FUNC (gtk_tree_view_search_init),
-     tree_view);
-  gtk_container_add (GTK_CONTAINER (window), entry);
-
-  /* done, show it */
-  tree_view->priv->search_dialog_position_func (tree_view, window);
-  gtk_widget_show_all (window);
-  gtk_widget_grab_focus (entry);
-
-  gtk_widget_event (entry, (GdkEvent *) event);
-
-  /* position window */
-
-  gtk_object_set_data (GTK_OBJECT (window), "text",
-                       gtk_entry_get_text (GTK_ENTRY (entry)));
-  gtk_object_set_data (GTK_OBJECT (tree_view), "search-dialog", window);
-
-  /* search first matching iter */
-  gtk_tree_view_search_init (entry, tree_view);
-}
-
 static gboolean
 gtk_tree_view_search_delete_event (GtkWidget *widget,
                                   GdkEventAny *event,
@@ -8842,7 +8870,7 @@ gtk_tree_view_search_delete_event (GtkWidget *widget,
   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
 
   gtk_tree_view_search_dialog_destroy (widget, tree_view);
-  
+
   return TRUE;
 }
 
@@ -8854,7 +8882,7 @@ gtk_tree_view_search_button_press_event (GtkWidget *widget,
   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
 
   gtk_tree_view_search_dialog_destroy (widget, tree_view);
-  
+
   return TRUE;
 }
 
@@ -8865,10 +8893,11 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget,
 {
   g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
   g_return_val_if_fail (GTK_IS_TREE_VIEW (tree_view), FALSE);
-  
+
   /* close window */
-  if (event->keyval == GDK_Escape || event->keyval == GDK_Return
-      || event->keyval == GDK_Tab)
+  if (event->keyval == GDK_Escape ||
+      event->keyval == GDK_Return ||
+      event->keyval == GDK_Tab)
     {
       gtk_tree_view_search_dialog_destroy (widget, tree_view);
       return TRUE;
@@ -8877,20 +8906,17 @@ gtk_tree_view_search_key_press_event (GtkWidget *widget,
   /* select previous matching iter */
   if (event->keyval == GDK_Up)
     {
-      gtk_tree_view_search_move (widget,
-                                tree_view,
-                                TRUE);
+      gtk_tree_view_search_move (widget, tree_view, TRUE);
       return TRUE;
     }
 
   /* select next matching iter */
   if (event->keyval == GDK_Down)
     {
-      gtk_tree_view_search_move (widget,
-                                tree_view,
-                                FALSE);
+      gtk_tree_view_search_move (widget, tree_view, FALSE);
       return TRUE;
     }
+
   return FALSE;
 }
 
@@ -8917,23 +8943,25 @@ gtk_tree_view_search_move (GtkWidget   *window,
     return;
 
   len = strlen (text);
-  
+
   if (len < 1)
     return;
 
   model = gtk_tree_view_get_model (tree_view);
   selection = gtk_tree_view_get_selection (tree_view);
-  
+
   /* search */
   gtk_tree_selection_unselect_all (selection);
   gtk_tree_model_get_iter_root (model, &iter);
-  
+
   ret = gtk_tree_view_search_iter (model, selection, &iter, text,
                                   &count, up?((*selected_iter) - 1):((*selected_iter + 1)));
-  
+
   if (ret)
-    /* found */
-    *selected_iter += up?(-1):(1);
+    {
+      /* found */
+      *selected_iter += up?(-1):(1);
+    }
   else
     {
       /* return to old iter */
@@ -8942,7 +8970,6 @@ gtk_tree_view_search_move (GtkWidget   *window,
       gtk_tree_view_search_iter (model, selection,
                                 &iter, text,
                                 &count, *selected_iter);
-
     }
 }
 
@@ -8966,12 +8993,12 @@ gtk_tree_view_search_equal_func (GtkTreeModel *model,
   normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
   case_normalized_string = g_utf8_casefold (normalized_string, -1);
   case_normalized_key = g_utf8_casefold (normalized_key, -1);
-  
+
   key_len = strlen (case_normalized_key);
 
   if (!strncmp (case_normalized_key, case_normalized_string, key_len))
     retval = FALSE;
-  
+
   g_value_unset (&value);
   g_free (normalized_key);
   g_free (normalized_string);
@@ -9014,7 +9041,7 @@ gtk_tree_view_search_iter (GtkTreeModel     *model,
 
              if (path)
                gtk_tree_path_free (path);
-              
+
               return TRUE;
             }
         }
@@ -9029,7 +9056,7 @@ gtk_tree_view_search_iter (GtkTreeModel     *model,
 
          while (node->left != tree->nil)
            node = node->left;
-         
+
          tmp = *iter;
          has_child = gtk_tree_model_iter_children (model, iter, &tmp);
          gtk_tree_path_append_index (path, 0);
@@ -9044,13 +9071,13 @@ gtk_tree_view_search_iter (GtkTreeModel     *model,
          do
            {
              node = _gtk_rbtree_next (tree, node);
-             
+
              if (node)
                {
                  gboolean has_next;
-                 
+
                  has_next = gtk_tree_model_iter_next (model, iter);
-                 
+
                  done = TRUE;
                  gtk_tree_path_next (path);
 
@@ -9090,7 +9117,7 @@ gtk_tree_view_search_iter (GtkTreeModel     *model,
 
   if (path)
     gtk_tree_path_free (path);
-  
+
   return FALSE;
 }
 
@@ -9107,10 +9134,10 @@ gtk_tree_view_search_init (GtkWidget   *entry,
   GtkTreeIter iter;
   GtkTreeModel *model;
   GtkTreeSelection *selection;
-  
+
   g_return_if_fail (GTK_IS_ENTRY (entry));
   g_return_if_fail (GTK_IS_TREE_VIEW (tree_view));
-  
+
   window = gtk_widget_get_parent (entry);
   text = gtk_entry_get_text (GTK_ENTRY (entry));
   len = strlen (text);
@@ -9126,14 +9153,14 @@ gtk_tree_view_search_init (GtkWidget   *entry,
 
   if (len < 1)
     return;
-  
+
   gtk_tree_model_get_iter_root (model, &iter);
-  
+
   ret = gtk_tree_view_search_iter (model, selection,
                                   &iter, text,
                                   &count, 1);
 
-  if (ret) 
+  if (ret)
     {
       selected_iter = g_malloc (sizeof (int));
       *selected_iter = 1;
@@ -9148,20 +9175,85 @@ gtk_tree_view_remove_widget (GtkCellEditable *cell_editable,
 {
   g_return_if_fail (tree_view->priv->edited_column != NULL);
   _gtk_tree_view_column_stop_editing (tree_view->priv->edited_column);
+  tree_view->priv->edited_column = NULL;
+
   gtk_container_remove (GTK_CONTAINER (tree_view),
                        GTK_WIDGET (cell_editable));
+  gtk_widget_grab_focus (GTK_WIDGET (tree_view));
+}
+
+static gboolean
+gtk_tree_view_start_editing (GtkTreeView *tree_view,
+                            GtkTreePath *cursor_path)
+{
+  GtkTreeIter iter;
+  GdkRectangle background_area;
+  GdkRectangle cell_area;
+  GtkCellEditable *editable_widget = NULL;
+  gchar *path_string;
+  guint flags = 0; /* can be 0, as the flags are primarily for rendering */
+  gint retval = FALSE;
+  GtkRBTree *cursor_tree;
+  GtkRBNode *cursor_node;
+
+  g_assert (tree_view->priv->focus_column);
+
+  if (_gtk_tree_view_find_node (tree_view, cursor_path, &cursor_tree, &cursor_node) ||
+      cursor_node == NULL)
+    return FALSE;
+
+  path_string = gtk_tree_path_to_string (cursor_path);
+  gtk_tree_model_get_iter (tree_view->priv->model, &iter, cursor_path);
+  gtk_tree_view_column_cell_set_cell_data (tree_view->priv->focus_column,
+                                          tree_view->priv->model,
+                                          &iter,
+                                          GTK_RBNODE_FLAG_SET (cursor_node, GTK_RBNODE_IS_PARENT),
+                                          cursor_node->children?TRUE:FALSE);
+  gtk_tree_view_get_background_area (tree_view,
+                                    cursor_path,
+                                    tree_view->priv->focus_column,
+                                    &background_area);
+  gtk_tree_view_get_cell_area (tree_view,
+                              cursor_path,
+                              tree_view->priv->focus_column,
+                              &cell_area);
+  if (_gtk_tree_view_column_cell_event (tree_view->priv->focus_column,
+                                       &editable_widget,
+                                       NULL,
+                                       path_string,
+                                       &background_area,
+                                       &cell_area,
+                                       flags))
+    {
+      retval = TRUE;
+      if (editable_widget != NULL)
+       {
+         gtk_tree_view_real_start_editing (tree_view,
+                                           tree_view->priv->focus_column,
+                                           cursor_path,
+                                           editable_widget,
+                                           &cell_area,
+                                           NULL,
+                                           flags);
+       }
+
+    }
+  g_free (path_string);
+  return retval;
 }
 
 static void
-gtk_tree_view_start_editing (GtkTreeView       *tree_view,
-                            GtkTreeViewColumn *column,
-                            GtkCellEditable   *cell_editable,
-                            GdkRectangle      *cell_area,
-                            GdkEvent          *event,
-                            guint              flags)
+gtk_tree_view_real_start_editing (GtkTreeView       *tree_view,
+                                 GtkTreeViewColumn *column,
+                                 GtkTreePath       *path,
+                                 GtkCellEditable   *cell_editable,
+                                 GdkRectangle      *cell_area,
+                                 GdkEvent          *event,
+                                 guint              flags)
 {
   tree_view->priv->edited_column = column;
   _gtk_tree_view_column_start_editing (column, GTK_CELL_EDITABLE (cell_editable));
+  gtk_tree_view_real_set_cursor (tree_view, path, FALSE);
   GTK_TREE_VIEW_SET_FLAG (tree_view, GTK_TREE_VIEW_DRAW_KEYFOCUS);
   gtk_tree_view_put (tree_view,
                     GTK_WIDGET (cell_editable),
@@ -9177,6 +9269,7 @@ gtk_tree_view_stop_editing (GtkTreeView *tree_view)
 {
   if (tree_view->priv->edited_column == NULL)
     return;
+
   gtk_cell_editable_editing_done (tree_view->priv->edited_column->editable_widget);
   gtk_cell_editable_remove_widget (tree_view->priv->edited_column->editable_widget);
 }
index 2c10f253c93728ab26c8d4ab564f70be00c24bd2..2ce8aafd83e8ef085398a7e27f86461129336d44 100644 (file)
@@ -96,6 +96,7 @@ struct _GtkTreeViewClass
                                           gboolean           expand,
                                           gboolean           open_all);
   void     (* select_cursor_parent)       (GtkTreeView       *tree_view);
+  void     (* start_interactive_search)   (GtkTreeView       *tree_view); 
 };
 
 
@@ -212,7 +213,9 @@ void                   gtk_tree_view_set_reorderable               (GtkTreeView
                                                                    gboolean                   reorderable);
 gboolean               gtk_tree_view_get_reorderable               (GtkTreeView               *tree_view);
 void                   gtk_tree_view_set_cursor                    (GtkTreeView               *tree_view,
-                                                                   GtkTreePath               *path);
+                                                                   GtkTreePath               *path,
+                                                                   GtkTreeViewColumn         *focus_column,
+                                                                   gboolean                   start_editing);
 
 
 /* Layout information */
index 7d477b0fa5f84ed2a1f6faaa74fc6c2c308eefb3..34e5608e8537c01c01e28edb660ba670dd5fe001 100644 (file)
@@ -2129,39 +2129,34 @@ gtk_tree_view_column_cell_get_size (GtkTreeViewColumn *tree_column,
     }
 }
 
-/**
- * gtk_tree_view_column_cell_render:
- * @tree_column: A #GtkTreeViewColumn.
- * @window: a #GdkDrawable to draw to
- * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
- * @cell_area: area normally rendered by a cell renderer
- * @expose_area: area that actually needs updating
- * @flags: flags that affect rendering
- * 
- * Renders the cell contained by #tree_column. This is used primarily by the
- * GtkTreeView.
- **/
-void
-gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
-                                 GdkWindow         *window,
-                                 GdkRectangle      *background_area,
-                                 GdkRectangle      *cell_area,
-                                 GdkRectangle      *expose_area,
-                                 guint              flags)
+/* both rendering and rendering focus are somewhat complicated, and a bit of
+ * code.  Rather than duplicate them, we put them together to keep the code in
+ * one place
+ */
+static void
+gtk_tree_view_column_cell_render_or_focus (GtkTreeViewColumn *tree_column,
+                                          GdkWindow         *window,
+                                          GdkRectangle      *background_area,
+                                          GdkRectangle      *cell_area,
+                                          GdkRectangle      *expose_area,
+                                          guint              flags,
+                                          gboolean           render,
+                                          GdkRectangle      *focus_rectangle)
 {
   GList *list;
   GdkRectangle real_cell_area;
   gint expand_cell_count = 0;
   gint full_requested_width = 0;
   gint extra_space;
+  gint min_x, min_y, max_x, max_y;
 
-  g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
-  g_return_if_fail (background_area != NULL);
-  g_return_if_fail (cell_area != NULL);
-  g_return_if_fail (expose_area != NULL);
+  min_x = G_MAXINT;
+  min_y = G_MAXINT;
+  max_x = 0;
+  max_y = 0;
 
   real_cell_area = *cell_area;
-    
+
   /* Find out how my extra space we have to allocate */
   for (list = tree_column->cell_list; list; list = list->next)
     {
@@ -2195,13 +2190,35 @@ gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
 
       real_cell_area.width = info->requested_width +
        (info->expand?extra_space:0);
-      gtk_cell_renderer_render (info->cell,
-                               window,
-                               tree_column->tree_view,
-                               background_area,
-                               &real_cell_area,
-                               expose_area,
-                               flags);
+      if (render)
+       {
+         gtk_cell_renderer_render (info->cell,
+                                   window,
+                                   tree_column->tree_view,
+                                   background_area,
+                                   &real_cell_area,
+                                   expose_area,
+                                   flags);
+       }
+      else
+       {
+         gint x_offset, y_offset, width, height;
+
+         gtk_cell_renderer_get_size (info->cell,
+                                     tree_column->tree_view,
+                                     &real_cell_area,
+                                     &x_offset, &y_offset,
+                                     &width, &height);
+
+         if (min_x > (real_cell_area.x + x_offset))
+           min_x = real_cell_area.x + x_offset;
+         if (max_x < real_cell_area.x + x_offset + width)
+           max_x = real_cell_area.x + x_offset + width;
+         if (min_y > (real_cell_area.y + y_offset))
+           min_y = real_cell_area.y + y_offset;
+         if (max_y < real_cell_area.y + y_offset + height)
+           max_y = real_cell_area.y + y_offset + height;
+       }
       real_cell_area.x += (info->requested_width + tree_column->spacing);
     }
   for (list = g_list_last (tree_column->cell_list); list; list = list->prev)
@@ -2227,6 +2244,59 @@ gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
                                flags);
       real_cell_area.x += (info->requested_width + tree_column->spacing);
     }
+  if (! render)
+    {
+      if (min_x >= max_x || min_y >= max_y)
+       {
+         *focus_rectangle = *cell_area;
+         focus_rectangle->x -= 1;
+         focus_rectangle->y -= 1;
+         focus_rectangle->width += 2;
+         focus_rectangle->height += 2;
+       }
+      else
+       {
+         focus_rectangle->x = min_x - 1;
+         focus_rectangle->y = min_y - 1;
+         focus_rectangle->width = (max_x - min_x) + 2;
+         focus_rectangle->height = (max_y - min_y) + 2;
+       }
+    }
+}
+
+/**
+ * gtk_tree_view_column_cell_render:
+ * @tree_column: A #GtkTreeViewColumn.
+ * @window: a #GdkDrawable to draw to
+ * @background_area: entire cell area (including tree expanders and maybe padding on the sides)
+ * @cell_area: area normally rendered by a cell renderer
+ * @expose_area: area that actually needs updating
+ * @flags: flags that affect rendering
+ * 
+ * Renders the cell contained by #tree_column. This is used primarily by the
+ * GtkTreeView.
+ **/
+void
+gtk_tree_view_column_cell_render (GtkTreeViewColumn *tree_column,
+                                 GdkWindow         *window,
+                                 GdkRectangle      *background_area,
+                                 GdkRectangle      *cell_area,
+                                 GdkRectangle      *expose_area,
+                                 guint              flags)
+{
+  g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
+  g_return_if_fail (background_area != NULL);
+  g_return_if_fail (cell_area != NULL);
+  g_return_if_fail (expose_area != NULL);
+
+  gtk_tree_view_column_cell_render_or_focus (tree_column,
+                                            window,
+                                            background_area,
+                                            cell_area,
+                                            expose_area,
+                                            flags,
+                                            TRUE,
+                                            NULL);
 }
 
 gboolean
@@ -2266,7 +2336,13 @@ _gtk_tree_view_column_cell_event (GtkTreeViewColumn  *tree_column,
                                                          background_area,
                                                          cell_area,
                                                          flags);
-      return (*editable_widget != NULL);
+
+      if (*editable_widget != NULL)
+       {
+         g_return_val_if_fail (GTK_IS_CELL_EDITABLE (*editable_widget), FALSE);
+
+         return TRUE;
+       }
     }
   return FALSE;
 }
@@ -2274,13 +2350,10 @@ _gtk_tree_view_column_cell_event (GtkTreeViewColumn  *tree_column,
 
 gboolean
 gtk_tree_view_column_cell_focus (GtkTreeViewColumn *tree_column,
-                                gint               direction,
-                                gboolean           unfocus)
+                                gint               direction)
 {
-  if (unfocus)
-    GTK_TREE_VIEW (tree_column->tree_view)->priv->focus_column = NULL;
-  else
-    GTK_TREE_VIEW (tree_column->tree_view)->priv->focus_column = tree_column;
+  if (GTK_TREE_VIEW (tree_column->tree_view)->priv->focus_column == tree_column)
+    return FALSE;
   return TRUE;
 }
 
@@ -2292,15 +2365,45 @@ gtk_tree_view_column_cell_draw_focus (GtkTreeViewColumn       *tree_column,
                                      GdkRectangle            *expose_area,
                                      guint                    flags)
 {
-  gtk_paint_focus (tree_column->tree_view->style,
-                  window,
-                  NULL,
-                  tree_column->tree_view,
-                  "treeview",
-                  cell_area->x,
-                  cell_area->y,
-                  cell_area->width-1,
-                  cell_area->height);
+  g_return_if_fail (GTK_IS_TREE_VIEW_COLUMN (tree_column));
+  if (tree_column->editable_widget)
+    {
+      /* This function is only called on the editable row when editing.
+       */
+
+      gtk_paint_focus (tree_column->tree_view->style,
+                      window,
+                      NULL,
+                      tree_column->tree_view,
+                      "treeview",
+                      cell_area->x - 1,
+                      cell_area->y - 1,
+                      cell_area->width + 2 - 1,
+                      cell_area->height + 2 - 1);
+      
+    }
+  else
+    {
+      GdkRectangle focus_rectangle;
+      gtk_tree_view_column_cell_render_or_focus (tree_column,
+                                                window,
+                                                background_area,
+                                                cell_area,
+                                                expose_area,
+                                                flags,
+                                                FALSE,
+                                                &focus_rectangle);
+      
+      gtk_paint_focus (tree_column->tree_view->style,
+                      window,
+                      NULL,
+                      tree_column->tree_view,
+                      "treeview",
+                      focus_rectangle.x,
+                      focus_rectangle.y,
+                      focus_rectangle.width - 1,
+                      focus_rectangle.height - 1);
+    }
 }
 
 gboolean
index 9bebfb8d6788282d20912a07baa76a3441404fcc..d8fdd6b0e2f0a0aa284a3e3521e43f5ea30a9822 100644 (file)
@@ -217,8 +217,7 @@ gboolean                gtk_tree_view_column_cell_event          (GtkTreeViewCol
                                                                  GdkRectangle            *cell_area,
                                                                  guint                    flags);
 gboolean                gtk_tree_view_column_cell_focus          (GtkTreeViewColumn       *tree_column,
-                                                                 gint                     direction,
-                                                                 gboolean                 unfocus);
+                                                                 gint                     direction);
 void                    gtk_tree_view_column_cell_draw_focus     (GtkTreeViewColumn       *tree_column,
                                                                  GdkWindow               *window,
                                                                  GdkRectangle            *background_area,
index ddb04fb83fc16dc14baddc33a015269779607bcc..44512c0616bfc4718c252bee8c838f992b65ec63 100644 (file)
@@ -35,6 +35,7 @@ noinst_PROGRAMS =             \
        $(testsocket_programs)  \
        testtext                \
         testtextbuffer         \
+       testtreeedit            \
        testtreeview            \
        testtreefocus           \
        testtreecolumns         \
@@ -52,6 +53,7 @@ testsocket_DEPENDENCIES = $(DEPS)
 testsocket_child_DEPENDENCIES = $(DEPS)
 testtext_DEPENDENCIES = $(TEST_DEPS)
 testtextbuffer_DEPENDENCIES = $(TEST_DEPS)
+testtreeedit_DEPENDENCIS = $(DEPS)
 testtreeview_DEPENDENCIES = $(DEPS)
 testtreefocus_DEPENDENCIES = $(DEPS)
 testtreecolumns_DEPENDENCIES = $(DEPS)
@@ -68,6 +70,7 @@ testselection_LDADD = $(LDADDS)
 testsocket_LDADD = $(LDADDS)
 testsocket_child_LDADD = $(LDADDS)
 testtextbuffer_LDADD = $(LDADDS)
+testtreeedit_LDADD = $(LDADDS)
 testtreeview_LDADD = $(LDADDS)
 testtreefocus_LDADD = $(LDADDS)
 testtreecolumns_LDADD = $(LDADDS)
@@ -79,6 +82,9 @@ testgtk_SOURCES =     \
        prop-editor.c   \
        testgtk.c       
 
+testtreeedit_SOURCES =         \
+       testtreeedit.c
+
 testtreeview_SOURCES = \
        prop-editor.c   \
        testtreeview.c 
index f0468ca6a8488b9dda6edb0634db2bc6ff146e47..c57eb07556c14a180e9061ab7533e19b26332a5e 100644 (file)
@@ -620,14 +620,14 @@ main (int argc, char *argv[])
   gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), 0, 0);
   gtk_box_pack_start (GTK_BOX (vbox2), bbox, TRUE, TRUE, 0);
 
-  button = gtk_button_new_with_label ("<<");
+  button = gtk_button_new_with_mnemonic ("<< (_Q)");
   gtk_widget_set_sensitive (button, FALSE);
   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_left_clicked), top_right_tree_view);
   g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (top_right_tree_view))),
                     "changed", GTK_SIGNAL_FUNC (selection_changed), button);
   gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
 
-  button = gtk_button_new_with_label (">>");
+  button = gtk_button_new_with_mnemonic (">> (_W)");
   gtk_widget_set_sensitive (button, FALSE);
   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_right_clicked), top_right_tree_view);
   g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (left_tree_view))),
@@ -639,14 +639,14 @@ main (int argc, char *argv[])
   gtk_button_box_set_child_size (GTK_BUTTON_BOX (bbox), 0, 0);
   gtk_box_pack_start (GTK_BOX (vbox2), bbox, TRUE, TRUE, 0);
 
-  button = gtk_button_new_with_label ("<<");
+  button = gtk_button_new_with_mnemonic ("<< (_E)");
   gtk_widget_set_sensitive (button, FALSE);
   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_left_clicked), bottom_right_tree_view);
   g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (bottom_right_tree_view))),
                     "changed", GTK_SIGNAL_FUNC (selection_changed), button);
   gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
 
-  button = gtk_button_new_with_label (">>");
+  button = gtk_button_new_with_mnemonic (">> (_R)");
   gtk_widget_set_sensitive (button, FALSE);
   gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (add_right_clicked), bottom_right_tree_view);
   g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (left_tree_view))),
diff --git a/tests/testtreeedit.c b/tests/testtreeedit.c
new file mode 100644 (file)
index 0000000..c9f5950
--- /dev/null
@@ -0,0 +1,140 @@
+#include <gtk/gtk.h>
+
+typedef struct {
+  const gchar *string;
+  gboolean is_editable;
+} ListEntry;
+
+enum {
+  STRING_COLUMN,
+  IS_EDITABLE_COLUMN,
+  NUM_COLUMNS
+};
+
+static ListEntry model_strings[] =
+{
+  {"A simple string", TRUE },
+  {"Another string!", TRUE },
+  {"Guess what, a third string. This one can't be edited", FALSE },
+  {"And then a fourth string. Neither can this", FALSE },
+  {"Multiline\nFun!", TRUE },
+  { NULL }
+};
+
+static GtkTreeModel *
+create_model (void)
+{
+  GtkListStore *model;
+  GtkTreeIter iter;
+  gint i;
+  
+  model = gtk_list_store_new (NUM_COLUMNS,
+                             G_TYPE_STRING,
+                             G_TYPE_BOOLEAN);
+
+  for (i = 0; model_strings[i].string != NULL; i++)
+    {
+      gtk_list_store_append (model, &iter);
+
+      gtk_list_store_set (model, &iter,
+                         STRING_COLUMN, model_strings[i].string,
+                         IS_EDITABLE_COLUMN, model_strings[i].is_editable,
+                         -1);
+    }
+  
+  return GTK_TREE_MODEL (model);
+}
+
+static void
+toggled (GtkCellRendererToggle *cell,
+        gchar                 *path_string,
+        gpointer               data)
+{
+  GtkTreeModel *model = GTK_TREE_MODEL (data);
+  GtkTreeIter iter;
+  GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
+  gboolean value;
+
+  gtk_tree_model_get_iter (model, &iter, path);
+  gtk_tree_model_get (model, &iter, IS_EDITABLE_COLUMN, &value, -1);
+
+  value = !value;
+  gtk_list_store_set (GTK_LIST_STORE (model), &iter, IS_EDITABLE_COLUMN, value, -1);
+
+  gtk_tree_path_free (path);
+}
+
+static void
+edited (GtkCellRendererText *cell,
+       gchar               *path_string,
+       gchar               *new_text,
+       gpointer             data)
+{
+  GtkTreeModel *model = GTK_TREE_MODEL (data);
+  GtkTreeIter iter;
+  GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
+
+  gtk_tree_model_get_iter (model, &iter, path);
+  gtk_list_store_set (GTK_LIST_STORE (model), &iter, STRING_COLUMN, new_text, -1);
+
+  gtk_tree_path_free (path);
+}
+
+gint
+main (gint argc, gchar **argv)
+{
+  GtkWidget *window;
+  GtkWidget *scrolled_window;
+  GtkWidget *tree_view;
+  GtkTreeModel *tree_model;
+  GtkCellRenderer *renderer;
+  
+  gtk_init (&argc, &argv);
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "GtkTreeView editing sample");
+  gtk_signal_connect (GTK_OBJECT (window), "destroy", gtk_main_quit, NULL);
+
+  scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_ETCHED_IN);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_container_add (GTK_CONTAINER (window), scrolled_window);
+
+  tree_model = create_model ();
+  tree_view = gtk_tree_view_new_with_model (tree_model);
+  gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree_view), TRUE);
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE);
+
+  renderer = gtk_cell_renderer_text_new ();
+  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
+                                              -1, "String",
+                                              renderer,
+                                              "text", STRING_COLUMN,
+                                              "editable", IS_EDITABLE_COLUMN,
+                                              NULL);
+
+  g_signal_connect (G_OBJECT (renderer), "edited",
+                   G_CALLBACK (edited), tree_model);
+  renderer = gtk_cell_renderer_toggle_new ();
+  g_signal_connect (G_OBJECT (renderer), "toggled",
+                   G_CALLBACK (toggled), tree_model);
+  
+  g_object_set (G_OBJECT (renderer),
+               "xalign", 0.0,
+               "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE,
+               NULL);
+  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
+                                              -1, "Editable",
+                                              renderer,
+                                              "active", IS_EDITABLE_COLUMN,
+                                              NULL);
+  gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
+  
+  gtk_window_set_default_size (GTK_WINDOW (window),
+                              650, 400);
+
+  gtk_widget_show_all (window);
+  gtk_main ();
+
+  return 0;
+}
index 08a3207c4ff6124f38fa7d144c08e482f31000c7..ca5afd318a378572d7b3b3582f8ccd7271b2a37f 100644 (file)
@@ -348,7 +348,7 @@ main (int argc, char *argv[])
                                                            renderer,
                                                            "active", ALEX_COLUMN,
                                                            "visible", VISIBLE_COLUMN,
-                                                           "can_activate", WORLD_COLUMN,
+                                                           "activatable", WORLD_COLUMN,
                                                            NULL);
   column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), col_offset - 1);
   gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), GTK_TREE_VIEW_COLUMN_FIXED);
@@ -381,7 +381,7 @@ main (int argc, char *argv[])
                                               renderer,
                                               "active", TIM_COLUMN,
                                               "visible", VISIBLE_COLUMN,
-                                              "can_activate", WORLD_COLUMN,
+                                              "activatable", WORLD_COLUMN,
                                               NULL);
   column = gtk_tree_view_get_column (GTK_TREE_VIEW (tree_view), col_offset - 1);
   gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (column), GTK_TREE_VIEW_COLUMN_FIXED);
index b9f285efa7029d87eaea6d7d0e6123067e3e576a..0dba6d29c64d7b04dd04cd019b629a9158bd2aee 100644 (file)
@@ -12,7 +12,7 @@ struct _ListSort
 
 static ListSort data[] =
 {
-  { "Apples", "Transmorgrify long word to demonstrate weirdness", "Exculpatory", "Gesundheit"},
+  { "Apples", "Transmogrify long word to demonstrate weirdness", "Exculpatory", "Gesundheit"},
   { "Oranges", "Wicker", "Adamantine", "Convivial" },
   { "Bovine Spongiform Encephilopathy", "Sleazebucket", "Mountaineer", "Pander" },
   { "Foot and Mouth", "Lampshade", "Skim Milk\nFull Milk", "Viewless" },